Skip to content

模块懒加载

这一节学习webpack中的模块懒加载功能。

其实vue和react中的懒加载都是基于它实现的。

底层是通过jsonp的形式将资源获取到,然后资源代码被挂载到了default属性上。

返回的结果是一个promise,可以通过.then获取到结果。

前置工作

我们模拟一下懒加载,页面有一个按钮,然后一点击按钮去加载某个资源。

修改配置文件

js
// webpack-optimize\webpack.config.js

let path = require('path')

// 插件 用来复制html入口模板,到打包后的目录,并把打包后的js文件,以script标签的形式塞到模板文件里
let HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    mode: 'development', // 模式,默认两种模式 production 和 development

    entry: {
        index: './src/index.js',
    },

    devServer: { // 开发服务器的配置
        port: 3000, // 默认端口是8080,这里可以改
        progress: true, // 打包时候的进度条
        contentBase: './dist', // 以哪个文件夹作为服务的根目录 ,如果有就直接使用,没有的话就使用内存中的
        open: true, // 服务启动完毕后,直接打开浏览器
        compress: true, // 启动gzip压缩
    },


    // 打包后的输出路径
    output: {
        filename: '[name].js', // 打包后的文件名
        path: path.resolve(__dirname, 'dist'), // 打包后输出的路径
    },

    // 配置一些loader
    module: {
        rules: [
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    // 配置一些它的选项
                    options: {
                        // 配置预设,有多个
                        presets: [
                            '@babel/preset-env', // 用来解析es6
                            '@babel/preset-react', // 用来解析react语法,jsx
                        ]
                    }
                }
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader'],
            },
        ]
    },
    // 注册插件
    plugins: [
        new HtmlWebpackPlugin({
            template: './public/index.html', // 模板的位置
        }),
    ]
}

新建source.js,模拟资源

js
// webpack-optimize\src\source.js
export default 'cheny hhh'

新建index.js

js
// webpack-optimize\src\index.js

let button = document.createElement('button')

button.innerHTML = 'hello'

button.addEventListener('click', () => {
    console.log('click');
})

document.body.appendChild(button)

运行下测试 npm run dev

image-20220128094750966

使用 import 语法实现懒加载

js
// webpack-optimize\src\index.js

let button = document.createElement('button')

button.innerHTML = 'hello'

button.addEventListener('click', () => {
    // console.log('click');
    // 点击后 动态加载 source模块
    // 草案中的语法 es6 通过jsonp来实现的 动态加载文件
    // 返回值是一个promise
    import('./source.js').then(data => {
        console.log(data);
    })
})

document.body.appendChild(button)

运行测试一下结果

image-20220128095116892

视频里的当时这个功能还需要安装一个 @babel/plugin-syntax-dynamic-import 插件

现在可能是已经通过协议了,成为了规范。

我们也来安装一下,学习一下配置方式

shell
yarn add @babel/plugin-syntax-dynamic-import@^7.2.0 -D

修改配置文件

js
// webpack-optimize\webpack.config.js

let path = require('path')

// 插件 用来复制html入口模板,到打包后的目录,并把打包后的js文件,以script标签的形式塞到模板文件里
let HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    mode: 'development', // 模式,默认两种模式 production 和 development

    entry: {
        index: './src/index.js',
    },

    devServer: { // 开发服务器的配置
        port: 3000, // 默认端口是8080,这里可以改
        progress: true, // 打包时候的进度条
        contentBase: './dist', // 以哪个文件夹作为服务的根目录 ,如果有就直接使用,没有的话就使用内存中的
        open: true, // 服务启动完毕后,直接打开浏览器
        compress: true, // 启动gzip压缩
    },


    // 打包后的输出路径
    output: {
        filename: '[name].js', // 打包后的文件名
        path: path.resolve(__dirname, 'dist'), // 打包后输出的路径
    },

    // 配置一些loader
    module: {
        rules: [
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    // 配置一些它的选项
                    options: {
                        // 配置预设,有多个
                        presets: [
                            '@babel/preset-env', // 用来解析es6
                            '@babel/preset-react', // 用来解析react语法,jsx
                        ],
                        // 模块懒加载 插件(现在好像已经不用安装了)
                        plugins: [
                            '@babel/plugin-syntax-dynamic-import',
                        ],
                    }
                }
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader'],
            },
        ]
    },
    // 注册插件
    plugins: [
        new HtmlWebpackPlugin({
            template: './public/index.html', // 模板的位置
        }),
    ]
}

我们来看一下懒加载的组件是怎么被打包的,npm run build

image-20220128095731495

异步加载的组件被单独拎出来了,当一点击按钮的时候就会加载这个0.js

总结

webpack中可以实现模块的懒加载。

当点击按钮的时候再加载这个资源。

使用方法:

js
button.addEventListener('click', () => {
    // console.log('click');
    // 点击后 动态加载 source模块
    // 草案中的语法 es6 通过jsonp来实现的 动态加载文件
    // 返回值是一个promise
    import('./source.js').then(data => {
        console.log(data);
    })
})

webpack会将懒加载的模块单独打包出来,当需要加载的时候,再单独请求这个资源。

其实vue和react中的懒加载都是基于它实现的。

底层是通过jsonp的形式将资源获取到,然后资源代码被挂载到了default属性上。

返回的结果是一个promise,可以通过.then获取到结果。

参考

https://www.bilibili.com/video/BV1a4411e7Bz?p=26&spm_id_from=pageDriver