webpack代码分离

Node.js / 431人浏览 / 0人评论

有三种代码分离的方法 入口起点:使用 entry 配置手动地分离代码。 防止重复:使用 Entry dependencies 或者 SplitChunksPlugin 去重和分离 chunk。 动态导入:通过模块的内联函数调用来分离代码。

代码分离

有三种代码分离的方法

入口起点:使用 entry 配置手动地分离代码。

防止重复:使用 Entry dependencies 或者 SplitChunksPlugin 去重和分离 chunk。

动态导入:通过模块的内联函数调用来分离代码。

入口起点(entry point)

项目(project)

webpack-demo
|- package.json
|- package-lock.json
|- webpack.config.js
|- /dist
|- /src
  |- index.js
 |- another-module.js
+|- /node_modules

another-module.js

import _ from 'lodash';

console.log(_.join(['Another', 'module', 'loaded!'], ' '));

webpack.config.js

 const path = require('path');

module.exports = {
-  entry: './src/index.js',
+  mode: 'development',
+  entry: {
+    index: './src/index.js',
+    another: './src/another-module.js',
+  },
   output: {
-    filename: 'main.js',
+    filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
 };

运行npm run build

...
$ npx webpack
asset index.bundle.js 554 KiB [compared for emit] (name: index)
asset another.bundle.js 554 KiB [emitted] (name: another)
runtime modules 2.5 KiB 12 modules
cacheable modules 532 KiB
  ./src/index.js 310 bytes [built] [code generated]
  ./src/another-module.js 82 bytes [built] [code generated]
  ./node_modules/lodash/lodash.js 531 KiB [built] [code generated]
webpack 5.82.1 compiled successfully in 216 ms

防止重复(prevent duplication)

入口依赖

配置 dependOn option 选项,这样可以在多个 chunk 之间共享模块

webpack.config.js

 const path = require('path');

module.exports = {
-   mode: 'development',
-   entry: {
+    index: './src/index.js',
+    another: './src/another-module.js',
+    index: {
+      import: './src/index.js',
+      dependOn: 'shared',
+    },
+    another: {
+      import: './src/another-module.js',
+      dependOn: 'shared',
+    },
+    shared: 'lodash',
   },
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
 };

webpack.config.js

 const path = require('path');

 module.exports = {
   mode: 'development',
   entry: {
     index: {
       import: './src/index.js',
       dependOn: 'shared',
     },
     another: {
       import: './src/another-module.js',
       dependOn: 'shared',
     },
     shared: 'lodash',
   },
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
+  optimization: {
+    runtimeChunk: 'single',
+  },
};

npm webpack

$ npx webpack
asset shared.bundle.js 550 KiB [emitted] (name: shared)
asset runtime.bundle.js 7.62 KiB [emitted] (name: runtime)
asset index.bundle.js 1.91 KiB [emitted] (name: index)
asset another.bundle.js 1.72 KiB [emitted] (name: another)
Entrypoint index 1.91 KiB = index.bundle.js
Entrypoint another 1.72 KiB = another.bundle.js
Entrypoint shared 558 KiB = runtime.bundle.js 7.62 KiB shared.bundle.js 550 KiB
runtime modules 3.66 KiB 8 modules
cacheable modules 532 KiB
  ./node_modules/lodash/lodash.js 531 KiB [built] [code generated]
  ./src/another-module.js 82 bytes [built] [code generated]
  ./src/index.js 310 bytes [built] [code generated]
webpack 5.82.1 compiled successfully in 219 ms

SplitChunksPlugin

webpack.config.js

const path = require('path');

  module.exports = {
    mode: 'development',
    entry: {
      index: './src/index.js',
      another: './src/another-module.js',
    },
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist'),
    },
+   optimization: {
+     splitChunks: {
+       chunks: 'all',
+     },
+   },
  };

npm run build

$ npm run build

> webpack-02-start@1.0.0 build
> webpack

asset vendors-node_modules_lodash_lodash_js.bundle.js 550 KiB [emitted] (id hint: vendors)
asset index.bundle.js 8.94 KiB [emitted] (name: index)
asset another.bundle.js 8.75 KiB [emitted] (name: another)
Entrypoint index 559 KiB = vendors-node_modules_lodash_lodash_js.bundle.js 550 KiB index.bundle.js 8.94 KiB
Entrypoint another 559 KiB = vendors-node_modules_lodash_lodash_js.bundle.js 550 KiB another.bundle.js 8.75 KiB
runtime modules 7.31 KiB 16 modules
cacheable modules 532 KiB
  ./src/index.js 310 bytes [built] [code generated]
  ./src/another-module.js 82 bytes [built] [code generated]
  ./node_modules/lodash/lodash.js 531 KiB [built] [code generated]
webpack 5.82.1 compiled successfully in 216 ms

动态导入(dynamic import)

webpack.config.js

 const path = require('path');

 module.exports = {
   mode: 'development',
   entry: {
     index: './src/index.js',
    another: './src/another-module.js',
   },
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
  optimization: {
    splitChunks: {
      chunks: 'all',
    },
  },
 };

### 目录(project)

webpack-demo
|- package.json
|- package-lock.json
|- webpack.config.js
|- /dist
|- /src
  |- index.js
- |- another-module.js
|- /node_modules

src/index.js

-import _ from 'lodash';
-
-function component() {
+function getComponent() {
-  const element = document.createElement('div');

-  // Lodash, now imported by this script
-  element.innerHTML = _.join(['Hello', 'webpack'], ' ');
+  return import('lodash')
+    .then(({ default: _ }) => {
+      const element = document.createElement('div');
+
+      element.innerHTML = _.join(['Hello', 'webpack'], ' ');

-  return element;
+      return element;
+    })
+    .catch((error) => 'An error occurred while loading the component');
 }

-document.body.appendChild(component());
+getComponent().then((component) => {
+  document.body.appendChild(component);
+});

webpack

$ webpack
asset vendors-node_modules_lodash_lodash_js.bundle.js 550 KiB [emitted] (id hint: vendors)
asset index.bundle.js 8.94 KiB [emitted] (name: index)
asset another.bundle.js 8.75 KiB [emitted] (name: another)
Entrypoint index 559 KiB = vendors-node_modules_lodash_lodash_js.bundle.js 550 KiB index.bundle.js 8.94 KiB
Entrypoint another 559 KiB = vendors-node_modules_lodash_lodash_js.bundle.js 550 KiB another.bundle.js 8.75 KiB
runtime modules 7.31 KiB 16 modules
cacheable modules 532 KiB
  ./src/index.js 310 bytes [built] [code generated]
  ./src/another-module.js 82 bytes [built] [code generated]
  ./node_modules/lodash/lodash.js 531 KiB [built] [code generated]
webpack 5.82.1 compiled successfully in 225 ms

src/index.js

-function getComponent() {
+async function getComponent() {
+  const element = document.createElement('div');
+  const { default: _ } = await import('lodash');

-  return import('lodash')
-    .then(({ default: _ }) => {
-      const element = document.createElement('div');
+  element.innerHTML = _.join(['Hello', 'webpack'], ' ');

-      element.innerHTML = _.join(['Hello', 'webpack'], ' ');
-
-      return element;
-    })
-    .catch((error) => 'An error occurred while loading the component');
+  return element;
 }

 getComponent().then((component) => {
   document.body.appendChild(component);
 });

预获取/预加载模块(prefetch/preload module)

LoginButton.js

//...
import(/* webpackPrefetch: true */ './path/to/LoginModal.js');

ChartComponent.js

//...
import(/* webpackPreload: true */ 'ChartingLibrary');
const lazyComp = () =>
  import('DynamicComponent').catch((error) => {
    // 在发生错误时做一些处理
    // 例如,我们可以在网络错误的情况下重试请求
  });
<script
  src="https://example.com/dist/dynamicComponent.js"
  async
  onerror="this.remove()"
></script>

转载注明:

扩展查找

0 条评论

还没有人发表评论

发表评论 取消回复

记住我的信息,方便下次评论
有人回复时邮件通知我