Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack实战(03)-单页面解决方案--代码分割和懒加载 #13

Open
liujie2019 opened this issue Feb 25, 2019 · 0 comments
Open

Comments

@liujie2019
Copy link
Owner

liujie2019 commented Feb 25, 2019

本节课讲解webpack4打包单页应用过程中的代码分割和代码懒加载。不同于多页面应用的提取公共代码,单页面的代码分割和懒加载不是通过webpack配置来实现的,而是通过webpack的写法和内置函数实现的。

目前webpack针对此项功能提供2种函数:

  • import(): 引入并且自动执行相关js代码;
  • require.ensure(): 引入但需要手动执行相关js代码。

代码目录如下:

image

其中,index.js是入口文件,subPageA.jssubPageB.js共同引用module.js。下面,我们按照代码引用的逻辑,从底向上展示代码:

module.js:

export default 'module';

subPageA.js:

import './module';
console.log('This is subPageA');
export default 'subPageA';

subPageB.js:

import './module';
console.log('This is subPageB');
export default 'subPageB';

注意:subPageA.jssubPageB.js两个文件中都执行了console.log()语句。之后将会看到import()和require()不同的表现形式:是否会自动执行js 的代码?

编写webpack配置文件:

const path = require('path');

module.exports = {
    mode: 'none',
    entry: './src/index2.js',
    output: {
        publicPath: __dirname + '/dist/',
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].bundle.js',
        chunkFilename: '[name].chunk.js'
    }
};

采用import()编写入口文件index.js,个人是非常推荐import()写法,因为和es6语法看起来很像。除此之外,import()可以通过注释的方法来指定打包后的chunk的名称。

除此之外,相信对vue-router熟悉的朋友应该知道,其官方文档的路由懒加载的配置也是通过import()来书写的。

采用import()编写index.js

index.js文件内容如下:

import(/* webpackChunkName: 'subPageA'*/ './subPageA').then(function(subPageA) {
    console.log(subPageA);
});

import(/* webpackChunkName: 'subPageB'*/ './subPageB').then(function(subPageB) {
    console.log(subPageB);
});

document.querySelector('#btn').onclick = () => {
    import(/* webpackChunkName: 'lodash'*/ 'lodash').then(function(_) {
        console.log(_.join(['1', '2']));
    });
}
export default 'page';

在命令行中运行webpack,打包结果如下:

image

我们创建index.html文件,通过<script>标签引入我们打包结果,需要注意的是:因为是单页应用,所以只要引用入口文件即可(即是上图中的main.bundle.js)。

index.html文件如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <button id="btn">按需加载</button>
    <script src="./dist/main.bundle.js"></script>
</body>
</html>

打开浏览器控制台,刷新界面,结果如下图所示:

image

图中圈出的部分,就是说明import()会自动运行subPageA.js和subPageB.js的代码。

NetWork选项中,我们可以看到,懒加载也成功了:

image

点击按需加载的按钮也会动态加载对应的chunk

image

采用require()编写index2.js

require.ensure()不会自动执行js代码,请注意注释。

require.include('./module.js'); // 将subPageA和subPageB共用的module.js打包在此page中
require.ensure(
    ['./subPageA.js', './subPageB.js'], // js文件或者模块名称
    function() {
      var subPageA = require('./subPageA'); // 引入后需要手动执行,控制台才会打印
      var subPageB = require('./subPageB');
    },
    'subPage' // chunkName
  );

  require.ensure(
    ['lodash'],
    function() {
      var _ = require('lodash');
      _.join(['1', '2']);
    },
    'lodash'
  );

  export default 'page';

打包结果如下:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

No branches or pull requests

1 participant