單頁應用——代碼分割

前提說明

在單頁應用中的代碼分割和多頁應用中的代碼分割有必定的區別:html

  • 多頁應用的代碼分割能夠經過 Webpack 的配置來實現
  • 單頁應用的代碼分割只能經過代碼中的動態指定 webpackChunkName 來實現

準備工做

爲了獲取一致的代碼體驗,這裏仍是習慣性的把所依賴的模塊貼出來:webpack

"devDependencies": {
    "webpack": "^4.17.1",
    "webpack-cli": "^3.1.0"
  },
  "dependencies": {
    "lodash": "^4.17.10"
  },
  "scripts": {
    "webpack": "webpack"
  }

因爲單頁應用的入口只有一個,且代碼分割的內容不是在配置文件中,而是在實際的代碼中,在這裏能夠直接把所須要的配置貼出來:web

const { resolve, join } = require('path');

module.exports = {
  mode: 'production',
  entry: {
    index: resolve(__dirname, './src/index.js')
  },
  output: {
    path: resolve(__dirname, './dist'),
    filename: '[name].bundle.js',
    chunkFilename: '[name].chunk.js',              // 根據 chunk name 生成對應的文件
    publicPath: join(__dirname, './dist/')      // 入口 bundle 查找其餘 chunk 依賴的路徑
  }
};

程序的入口是 index.js,頁面中存在兩個組件 headerfooter,這兩個組件又共同引入了組件 component.js,在代碼中體現,以下:json

index.jsbash

import './header';
import './footer';

header/index.jsui

import '../component/component';

console.log('header section ...');

export default 'footer';

footer/index.jscode

import '../component/component';

console.log('footer section ...');

export default 'footer';

component/component.jscomponent

import _ from 'lodash';

console.log(_.join(["Hello", "lodash"]));

export default 'component';

建立一個 index.html 加入打包後的入口 js,爲了便於觀察效果:htm

<body>
  <script src="./dist/index.bundle.js"></script>
</body>

未進行代碼分割的效果

準備工做完成以後,首先來看一下沒有通過代碼分割的效果。首先執行命令:yarn webpackip

Asset      Size  Chunks             Chunk Names
index.bundle.js  1.07 KiB       0  [emitted]  index
Entrypoint index = index.bundle.js

這個時候全部的代碼都會打包到 index.bundle.js 中,也就是沒有進行代碼分割。

進行代碼分割

下面的操做就是把全部的代碼都分割成單獨的 chunk,便於懶加載(懶加載下篇文章說明)。

若是要把全部的 module 都分割成單獨的 chunk,就須要使用 import() 方法,而且在該方法的參數中指定 webpackChunkName 來告訴 Webpack 如何分離 chunk。

index.js

import(/* webpackChunkName: 'header' */ './header').then(module => {
  console.log(module);
}).catch(err => {
  console.log(err);
});
import(/* webpackChunkName: 'footer' */ './footer').then(module => {
  console.log(module);
}).catch(err => {
  console.log(err);
});

header/index.js

import(/* webpackChunkName: 'component' */ '../component/component').then(module => {
  console.log('in header : ', module);
}).catch(err => {
  console.log(err);
});

console.log('header section ...');

export default 'footer';

footer/index.js

import(/* webpackChunkName: 'component' */ '../component/component').then(module => {
  console.log('in footer : ', module);
}).catch(err => {
  console.log(err);
});

console.log('footer section ...');

export default 'footer';

component/component.js

import(/* webpackChunkName: 'lodash' */ "lodash").then(function(_) {
  console.log(_.join(["Hello", "lodash"]));
});

export default 'component';

執行命令後的效果:

Asset       Size  Chunks             Chunk Names
        index.bundle.js   2.24 KiB       0  [emitted]  index
        header.chunk.js  247 bytes       1  [emitted]  header
        footer.chunk.js  248 bytes       2  [emitted]  footer
     component.chunk.js  212 bytes       3  [emitted]  component
vendors~lodash.chunk.js   69.5 KiB       4  [emitted]  vendors~lodash
Entrypoint index = index.bundle.js
相關文章
相關標籤/搜索