Is rollup for library? !

Write in front


Rollup was designed with libraries rather than apps in mind, and it is a perfect fit for React’s use case.

I saw this in Behind the Scenes: Improving the Repository Infrastructure – React Blog. I was a little surprised. Why is such a good thing only for class libraries? What makes it unsuitable for building apps?

Zero.webpack
Is rollup for library?  !

webpack is committed to the modular construction of complex SPAs. What is very attractive are various loaders:


Essentially, webpack loaders transform all types of files into modules that can be included in your application’s dependency graph.

Handle various resource dependencies in a consistent way, shielding resource type differences through loader (js is module, css is module, img is also module...), the advantages are as follows:


No more carefully placing your files in the right folders and hacked-together scripts for adding hashes to file URLs — webpack can take care of it for you.

Other very powerful features include:

Code Splitting: On-demand loading/parallel loading in the production environment

Tree Shaking: Remove useless code (export) when building

HMR: Hot replacement of modules in development

Commons Chunk: extract common dependencies during construction

Dependency Graph: After the build is completed, the output module dependency graph makes the bundle readable

1. The original intention
rollup is for ES6 module from the beginning:


Next-generation ES6 module bundler.

At that time, the format dispute between AMD, CMD, and UMD was still very hot, and the ES6 module had not yet been implemented in a browser. rollup just came out


Rollup was created for a different reason: to build flat distributables of JavaScript libraries as efficiently as possible, taking advantage of the ingenious design of ES2015 modules.

(Quoted from Webpack and Rollup: the same but different, written by the author of rollup)

I hope to make full use of the ES6 module mechanism to build a class library bundle with flat structure and outstanding performance, which is designed for library

2. Core advantages


It solves one problem well: how to combine multiple modules into a flat file with minimal junk code in between.

The amazing thing about rollup is the cleanliness of its bundle, especially the iife format, the content is very clean, there is no extra code, it is really just that the modules are spliced ​​in order of dependency.

This is related to the module processing idea of ​​rollup:


To achieve this, instead of turning modules into functions like many other bundlers, it puts all the code in the same scope, and renames variables so that they don’t conflict. This produces code that is easier for the JavaScript engine to parse, for a human to read, and for a minifier to optimize.

All modules are placed flat in the outermost scope of the bundle file. There is no scope isolation between modules, and renaming is used to solve the problem of naming conflicts in the same scope. Several obvious benefits:

Runtime performance (flat code structure for easy analysis)

Bundle source code readability (natural order structure, no module definition/jump)

Compression can be optimized (no module definitions and other uncompressed boilerplate code)

The disadvantages of this are also obvious:

The module system is too static, and features such as HMR are difficult to achieve

Only for ES6 modules, cannot reliably handle cjs and umd dependencies (you will encounter problems every time you use rollup-plugin-commonjs)

If it is only for lib, it does not matter if the first point is not supported, but the second point is really a headache. The secondary dependency is uncontrollable. It is always inevitable that you will encounter some problems that cjs modules cannot be automatically converted to ES6 modules. E.g:


‘foo’ is not exported by bar.js (imported by baz.js)

Some scenarios can be solved unhappily by the way of Troubleshooting through namedExports, other times through external or globals, and there are even solutions that need to adjust the order of plugin applications... But there is no way to completely solve this kind of problems:


Webpack gets around the need for namedExports by keeping everything as CommonJS modules and implementing Node’s require system in the browser, which is why the resulting bundles are larger and take longer to start up. Both options are valid, but that’s the tradeoff to be aware of — more config (Rollup, when using modules like React), or larger bundles (webpack).

(引自Is “named exports” feature or bug?)

Although cjs will eventually become history, there are still quite a few cjs modules in npm at present and now. Whether it is SPA or library, they still face the problem of dealing with cjs module dependencies.

3. Selection principle
Use webpack for apps, and Rollup for libraries

For building App, webpack is more suitable, if it is a class library, of course rollup is better

The advantages of webpack to build App are reflected in the following aspects:

Powerful plugin ecology, mainstream front-end frameworks have corresponding loader

App-oriented feature support, such as the aforementioned HMR, Code Splitting, Commons Chunk, etc. are all necessary features for app development

Simplify all aspects of Web development, including automatic base64 for pictures, resource caching (chunkId), code splitting by route, lazy loading, etc. It is not difficult to achieve

Reliable handling of dependent modules, unlike rollup facing cjs problems, __webpack_require__ does not have these troubles

Rollup does not have these advantages, and you will encounter some problems that are not easy to solve when doing code splitting. If you do not have enough time and grasp, do not easily try to use rollup as an App building tool

The advantage of rollup lies in the high-efficiency bundle, which is exactly what the library is pursuing. Even if it takes a little setback (as React 16 does), it is worth it for performance

Note that this principle only says to use the right tool to do the right thing. It is suitable for most general scenarios. It is also very common to use rollup to build App and webpack to build class libraries:


That’s not a hard and fast rule — lots of sites and apps are built with Rollup, and lots of libraries are built with webpack. But it’s a good rule of thumb.

Typically, if the business itself does not rely on too many third-party modules, and the style convention follows the ES6 module, it is also appropriate to build an App with rollup (Code Splitting, etc.)

PS In addition, rollup is not easy to perform stream-based extensions like glup or webpack, such as separating three parts from a vue file and processing separately (vue plugin does not seem to support ts)

4. External dependencies are

for React and other classes Libraries should be separated as third-party dependencies as much as possible, instead of being built into bundles, for several reasons:

Performance will deteriorate. For example, React 16 took a lot of effort to switch to rollup + GCC (Google Closure Compiler), which reached 109kb. I compiled it once and went back to before liberation.

It is not conducive to caching. Class libraries are not updated frequently and can be used as static resources to give full play to the advantages of caching. The content of manual build is affected by tool configuration

External dependencies can be marked through external + globals configuration under rollup:


external: ['react', 'react-dom'],
output: {
  globals: {
    'react': 'React',
    'react-dom': 'ReactDOM'
  }
}

The bundle generated in this way is:


// iife
(function (React,ReactDOM) {
    //...
}(React,ReactDOM));

// cjs
var React = _interopDefault(require('react'));
var ReactDOM = _interopDefault(require('react-dom'));

Therefore, the business code is generally packaged into iife, and then the third-party CDN class library is referenced through script:


<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<!-- 或者聚合的版本 -->
<script crossorigin src="//cdn.jsdelivr.net/combine/npm/[email protected]/umd/react.production.min.js,npm/[email protected]/umd/react-dom.production.min.js"></script>

PSrollup's external and globals are a bit strange, whether it is key or value, or these two things have to be used together, for more information, please see [question] Difference between externals and globals

reference

Webpack and Rollup: the same but different: very interesting Found too late

Handling 3rd-party JavaScript with Rollup

Guess you like

Origin blog.51cto.com/15080030/2592709