4

Background

I am trying to develop with Webpack and JavaScript. Webpack would bundle all source code into one single file. When application becomes large, the file would be very large and cause negative impact to the performance.

Webpack

Webpack provided feature named code splitting which would split the bundle output into different according the predefined entry point. It would help increase the performance if the application become too large. However, It required to restructure the application and deeply understand the application, then the application spitted into different modules which would be the entry points for build. Also, it would requires code change when another required to call the function by Lazy Loading.

SystemJs

SystemJs is a dynamic Es Module Loader which would lazy load the required module in Runtime.

Question

Should I use webpack for large-sale application?

Possible Solution

JavaScript Source Code Bundling is necessary for large application but the application may be spitted into sub-modules and may be lazy load into application if the sub module is loaded.

Update

stage 3 proposal specific the dynamic import syntax which would used to solve my problem (lazy load for specific part).

import('./test.js').then(function(Test){
  var test = new Test.default();
  test.doSomething()
})

Which is similar to

import Test from './test';
var test = new Test();
test.doSomething();

Webpack support

It required to config the public path, chunkFilename and add syntax-dynamic-import for enable new syntax (import()).

const path = require('path');

module.exports = {
    entry: {
        app:    './src/app.js'
    },
    output: {
        publicPath: 'bin/',
        path: path.resolve(__dirname, 'bin'),
        filename: '[name].bundle.js',
        chunkFilename: '[name].bundle.js'
    },
    devtool: 'source-map',
    module: {
        loaders: [
            {
                test: /\.js$/,
                loaders: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: ['es2015'],
                            plugins: ["syntax-dynamic-import"]
                        }
                    }
                ]               
            }
        ]
    }
}; 
Ben Cheng
  • 349
  • 1
  • 10
  • 1
    You used the term "lazy load" in your title, but did not clarify further. – Robert Harvey Dec 02 '17 at 15:00
  • @RobertHarvey, Thanks for comment. I have add some descriptions of SystemJs for Lazy Load. – Ben Cheng Dec 02 '17 at 17:50
  • @BenCheng the reality is that bundling is still necessary for production in 2017. Importantly, your ability to break up your app depends on any frameworks that you use as well. For example Angular requires explicit, eager component and service registration yet can be broken up along certain framework specific lines that are well defined. – Aluan Haddad Dec 02 '17 at 19:03
  • @AluanHaddad, Is there any drawback if I do not bundle source code? For example, I used AngularJs 1.4 and the javascript does not bundle for production. Almost all source codes are imported into browser by OzLazyLoad. – Ben Cheng Dec 03 '17 at 02:10
  • @BenCheng it's just a question of startup performance. If it's fast enough for your use case then no you don't need to bundle unless you use Webpack or Browserify. They are the only ones out of these options that _require_ bundling. In other words they understand modules only by bundling them which, since most want to bundle, is good enough for many. They doesn't let you run unbundled even during development. Try SystemJS (via JSPM: see disclaimer in answer) or RequireJS. – Aluan Haddad Dec 03 '17 at 02:17
  • I saw your update but the Webpack config you posted is for version 1 but it's well into version 3 which uses different config. – Aluan Haddad Dec 03 '17 at 09:30
  • I do not know the difference between version 1 and version 3. Could you help to update the config? – Ben Cheng Dec 03 '17 at 09:48
  • I could but I want to confirm first that you are indeed not coupled to using an old version of webpack. – Aluan Haddad Dec 03 '17 at 21:54

1 Answers1

3

All mature JavaScript loading and bundling tools, from Webpack to RequireJS to SystemJS, provide techniques for doing this.

In Webpack it's enabled by a feature known as code splitting.

In SystemJS it's enabled by features such as bundle arithmetic, dep caching, and bundle injection and is provided by JSPM or direct usage of the SystemJS Builder.

I forget the terminology for RequireJS but the functionality exists there as well and is provided by r.js.

So just research.

But, to answer your direct question, all of these tools, including Webpack, are suitable for developing large applications. In fact they excel at it. My personal preference is not for Webpack but rather for JSPM.

As Ben Cheng notes, Webpack's code splitting approach requires you to structure your application in terms of different entry points, which you can morally think of as sub packages or sub apps. That said, this structuring technique plays a role in splitting up bundles in all of these tools.

Breaking down your application into these more independent units can be a difficult task.

Disclaimer: I am a member of the JSPM team

Aluan Haddad
  • 678
  • 4
  • 9
  • 1
    Yes. Webpack provide the technique of code splitting but it requires to define the entry point of different modules. Sometimes, it is not easy to define a modules and define a point of lazy loading in my application. – Ben Cheng Dec 02 '17 at 13:38
  • @BenCheng that's true, and it's one of the reasons why I prefer the bundle arithmetic approach, because it traces the module tree, inferring shared dependencies and capturing them – Aluan Haddad Dec 02 '17 at 13:40
  • @BenCheng I added a note with your comments to the answer – Aluan Haddad Dec 02 '17 at 13:44
  • Do you think that requirejs as amd is better solution for a large scale web application. I.e. System.import(entryfile) – Ben Cheng Dec 02 '17 at 13:48
  • @BenCheng it could be but they all support async loading vis such imperative constructs. RequireJS is definitely the veteran in terms of this feature. Nowadays, you can use constructs in all of these loaders that are syntactically agnostic. Specifically, the new dynamic `import` statement, which is currently a stage ECMAScript proposal and is supported by transpilers such as TypeScript and Babel. The transpiler will choose the appropriate translation of this construct based on the target module format, e.g. `context.import` inside of a `System.register` call. This increases portability – Aluan Haddad Dec 02 '17 at 13:53
  • I meant a stage 3 proposal – Aluan Haddad Dec 02 '17 at 19:05