webpack代码分割

251 阅读3分钟
entry:{
// 多入口:有一个入口,最终输出就有一个和bundle
// 会生成两个js文件
    main:"",
    test:""
},
output:{
    filename:"js/[name].[contenthash:10].js"
   path:resolve(__dirname,'build')
},
/*
    可以将node_modules中代码单独打包成一个chunk最终输出
    如果有一个第三方js在不同js里被引入的话通过这个最后也只会打包出同一个文件
*/
optimization:{
    splitChunks:{
        chunks:"all"
    }
}

1、多入口

2、optimization 单独打包node_modules

3、通过js代码,让某个文件单独打包成一个chunk

import(/* webpackChunkName: 'test' */'./test')
    .then()
    .catch()

hmr

devserver:{
    hot:true
}

if(module.hot){
// module.hot为true说明hmr打开了
    module.hot.accept('监听的文件名',function(){})
}

懒加载

   document.getElementById('btu').onclick=function(){
       // webpackChunkName:'文件名',
       // webpackPrefetch:true 预加载 在使用之前就缓存了 调用的时候使用的时候缓存的
       // 正常加载可以认为是并行加载(同一时间加载多个文件)
       // 预加载 prefetch:等其他资源加载完成,浏览器空闲了再偷偷加载
       import(/* webpackChunkName:'test',webpackPrefetch:true */'需要按需加载的js文件').then(({mul}) => {
           console.log(mul())
       })
   }

PWA(渐进式网页应用(离线可访问)) workbox --> workbox-webpack-plugin npm i workbox-webpack-plugin -D

webpack.config.js

const WorkboxWebpackPlugin = require('workbox-webpack-plugin')
plugins:[
    new WorkboxWebpackPlugin.GenerateSw({
        clientsClaim:true, // 1、帮助我们serviceworker快速启动
        skipWaiting:true, // 2、删除旧的serviceworker
        //  会生成一个serviceworker配置文件~
    })
]

js

/*
 1、eslint不认识window、navigator全局变量
 解决:需要修改package.json中的eslintConfig配置
     "env":{
         "browser":true // 支持浏览器端全局变量
     }
 2、serviceworker代码必须运行在服务器上
 --》nodejs
 --> npm i serve -g
     serve -s build 启动服务器,将build目录下所有资源作为静态资源暴露出去
*/
// 注册serviceworker
// 处理兼容性问题
if('serviceWorker' in navigator){
    window.addEventListener('load',() => {
        navigator.serviceWorker.register('/servive-worker.js')
        .then(() => {})
        .catch(() => {})
    })
}

image.png

多进程打包

npm i thread-loader -D

{
    test:/\.js$/,
    exclude:/node_modules/,
    use:[
    // 开启多进程打包
    // 进程启动大概要600ms,进程通信也有开销
    // 只有工作消耗时间比较长,才需要多进程打包
     // 'thread-loader',
        {
            loader:"thread-loader",
            options:{
                workers:2 // 进程2个
            }
        },
        {
            loader:'babel-loader',
            options:{
                presets:[
                    '@babel/preset-env',
                    {
                        useBuiltIns:'usage',
                        corejs:{version:3},
                        targets:{
                            chrome:"60",
                            firefox:"50"
                        }
                    }
                ],
                // 开启babel缓存
                // 第二次构建时,会读取之前的缓存
                cacheDirectory:true
                // 可以让第二次打包速度构建更快
            }
        }
    ]
    
} 

externals

externals:{
    // 要忽略的一个库名 -- npm包名
   // 拒绝jQuery这个包被打包进来
    jquery:"jQuery"
}

dll

可以将不同的库打包成不同的chunk

比如jQuery react vue

当你运行webpack时,默认使用webpack.config.js配置

使用 webpack --config webpack.dll.js 运行webpack.dll.js文件

npm i add-asset-html-webpack-plugin -D

const {resolve} = require('path')
const webpack = require('webpack')
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin')
module.exports = {
   entry:{
         // 最终打包生成的[name] --> jquery
        // ['jquery'] --> 要打包的库是jquery
        jquery:['jquery']
   },
   output:{
       filename:'[name].js',
       path:resolve(__dirname,'dll'),
       library:'[name]_[hash]', // 打包的库里面向外面暴露出去的内容叫什么名字
   },
   plugins:[
       // webpack.dll.js 将第三方打包到一起
       // 打包生成一个manifest.json --> 提供和jquery映射
       new webpack.DllPlugin({
           name:"[name]_[hash]", // 映射的暴露的内容名称
           path:resolve(__dirname,'dll/manifest.json')
       }),
        // webpack.config.js 默认引用不用再重新打包
       // 在执行完上面的DllPlugin会生成一个manifest.json的基础上执行以下代码
       // 告诉webpack那些库不参与打包,同时使用时名称也得变
       new webpack.DllReferencePlugin({
           manifest: resolve(__dirname,'dll/manifest.json')
       }),
       // 将某个文件打包输出出去,并在html中自动引入该资源
       new AddAssetHtmlWebpackPlugin({
           filepath:resolve(__dirname,'dll/jquery.js')
       })
   ],
   mode:"production"
 
}