airbnb / goji-js

React ❤️ Mini Program
https://goji.js.org
MIT License
224 stars 27 forks source link

Support nohoist feature #120

Closed malash closed 3 years ago

malash commented 3 years ago

Sub Packages is a common concept in most Mini Program platforms to improve load performance and code structure. It can be regarded as chunk split in Web development.

Here are some useful links to their official documents.

Problems

The original design of sub packages based code splitting result in several limitations. A sub package cannot require any module in the main package nor other sub packages.

Developers have to place shared code in main package manually, otherwise they will get a compile error from the Mini Program dev tool. In another hand, if a module was only required by a sub package, developers should move it into the sub package to reduce size of main package.

Hoist and nohoist

In GojiJS, we use Webpack to analyze module dependencies and bundle the code. With code splitting we are able to import dependents in a sub package from anywhere we want, like the main package, node_modules or even other sub packages. GojiJS can hoist the shared code into a common chunk file ( usually _goji_commons.js ) in the main package.

Here is an example that has 5 pages, one is in the main package and others are in 2 sub packages ( packageA and packageB ).

sub packages example

GojiJS hoist modules to root common chunk. By doing this the dependencies can match Mini Program sub packages' limitations.

hoist example

nohoist.enable

boolean = true if in production mode, otherwise false.

In above example, redux and date-fns are not shared code so they can be moved into sub packages to reduce size of main package. We call that optimization nohoist.

You can change nohoist.enable option in goji.config.js to toggle this feature.

nohoist.enable is set to false in development mode to speed up code bundling.

nohoist.enable example

nohoist.maxPackages

number = 1

Some modules, like lodash in the example, are shared only by sub packages. It is possible to forked them into sub packages. Although the size of total packages increases, it does reduce the size of main package.

To enable this feature, you can set nohoist.maxPackages to a number N above 1. A module shared less than or equal N will be forked into packageName/_goji_nohoist_[contenthash].js.

nohoist.maxPackages example

Although the code are duplicated, the runtime closure is still a singleton. For more details see Independent packages.

Please note this feature may heart user lading time because more duplicated code are generated. You should only use it if size of main package was exceeded or about to exceed.

nohoist.test

function (module, chunks) => boolean RegRex string

You can use this options to nohoist specific modules.