# webpack-config **Repository Path**: isfy/webpack-config ## Basic Information - **Project Name**: webpack-config - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-04-09 - **Last Updated**: 2021-11-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 基础配置 ## enrty 入口文件 1. String -->'./index.js' 打包形成一个chunk,输出一个bundle文件 ```webpack.config.js { entry:'./index.js' } ``` 2. Array 所有入口文件最终只会形成一个chunk文件,输出一个bundle 用途:在HMR功能中让html热更新生效 ```webpack.config.js { entry:['./src/js/index.js','./src/js/test.js'] } ``` 3. Object 几个入口就输出几个chunk,输出几个bundle ```webpack.config.js { entry:{ main:'./src/js/index.js', test:'./src/js/test.js' } } ``` # 优化 ## 开发环境性能优化 ### 优化打包速度 * HMR ```webpack.config.js { // html 启用热更新 entry:['./src/index.js','./index.html'], ... devServer:{ contentBase:resolve(__dirname,'dist'), compress:true, open:true, hot:true // js启用热更新 } } ``` ```index.js import print from './print.js' // 如果启用了热更行 if(module.hot){ // 监听 ./print.js 改变,执行回调函数 module.hot.accpet('./print.js',function(){ }) } ``` ### 优化代码调试 * source-map 一种提供源代码到构建后代码映射技术 组合: [inline-|hidden-|eval-][nosource-][cheap-[module-]]source-map 可选: source-map 外部 错误代码的准确信息,和源代码的错误位置 inline-source-map 内联 错误代码的准确信息,和源代码的错误位置 hidden-source-map 内联 错误代码原因,但是没有错误位置 不能最终源代码错误,只能提供构建后代码的错误位置 eval-source-map 内联 每一个文件都生成一个对应的source-map,都在eval 错误代码的准确信息,和源代码的错误位置 nosource-source-map 外部 错误代码准确信息,但是没有任何源代码信息 cheap-source-map 外部 错误代码的准确信息,和源代码的错误位置 module会将loader的source-map加入 内联和外部的区别: 1.外部生成了文件,内联没有 2.内联构建速度快 开发环境:速度快,调试友好 速度快(eval>inline>cheap>...) eval-cheap-source-map eval-source-map 生产环境:源代码要不要隐藏,调试要不要更友好 内联会让代码体积变大,所有生成环境不用内联 nosource-source-map 全部隐藏 hidden-source-map 隐藏源代码,提示构建后的代码信息 -->source-map / cheap-module-source-map ## 生产环境性能优化 ### 优化打包构建速度 * oneOf 成功匹配一个loader后,不再继续匹配剩下的loader ```webpack.config.js { module:{ rules:[ ... { oneOf:[ { test:/\.css$/, loader:['style-loader','css-loader'] }, { test:/\.less$/, loader:['style-loader','css-loader','less-loader'] }, ... ] } ] } } ``` * bable缓存 让第二次构建速度更快 ```webpack.config.js { module:{ rules:[ { test:/\.js$/, loader:'bable-loader', options:{ cacheDirectory:true } } ] } } ``` * 多线程打包 依赖于thread-loader ```webpack.config.js // webpack.config.js { module:{ rules:[ { test:/\.js$/, exclude:/node_modules/, use:{ /* 开启多进程打包 进程启动大概为600ms,进程通信也有开销。 只有工作消耗时间比较长,才需要多进程打包 */ // 'thread-loader', { loader:'thread-loader', options:{ workers:2 // 进程数量 } }, { loader:'babel-loader', options:{ presets:[ '@babel/preset-env', { useBuiltIns:'usage', corejs:{version:3}, targets:{ chrome:'60' } } ] } } } } ] } } ``` * externals 忽略指定npm包 ``` { externals:{ jquery:'jQuery' } } ``` * dll 使用dll技术对某些库(第三方库:jquery、react、vue...)进行单独打包 ```webpack.dll.js // webpack.dll.js const {resolve} = require('paht') const webpack = require('webpack') module.exports = { entry:{ // 最终打包生成 jquery // ['jquery] --> 要打包的库jquery jquery:['jquery'] }, output:{ filename:'[name].js', path:resolve(__dirname,'dll'), library:'[name]_[hash]', // 打包的库里面向外暴露出去的内容叫什么名字 }, plugins:[ // 打包生成一个manifest.json -->提供和jquery映射 new webpack.DllPlugin({ name:'[name]_[hash]', // 映射库暴露的内容名称 path:resolve(__dirname,'dll/manifest.json') // 输出文件路径 }) ] } ``` ```webpack.config.js // webpack.config.js const webpack = require('webpack) const resolve = require('path) const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin') { plugins:[ // 告诉webpack哪些库不参与打包,同时使用时的名称也得变 new webpack.DllReferencePlugin({ manifest:resolve(__dirname,'dll/manifest.json') }), // 将某个文件打包输出,并在html中自动引入 new AddAssetHtmlWebpackPlugin({ filepath:resolve(__dirname,'dll/jquery.js') }) ], mode:'production' } ``` ### 优化代码运行的性能 * 缓存--文件资源缓存 让代码上线运行缓存更好使用 1. hash 每次webpack构建时会生成一个唯一的hash值 js和css同时使用一个hash值 如果重新打包,会导致所有缓存失效 2. chunkhash 根据chunk生成的hash值 如果打包来源与同一个chunk,那么hash值就一样 问题:js和css的hash值还是一样的; 因为css是在js中被引入的,所以同属于一个chunk 3. contenthash 根据文件的内容生成hash值,不同文件hash值一定不一样 * tree shaking 前提: 1.必须使用ES6模块化 2.开启production环境 作用:减少代码体积 ```package.json /* 所有代码都没有副作用(都可以进行tree shaking) 问题:可能会把css / @babel / polyfill (副作用)文件干掉 */ sideEffects":false, // 解决方法 "sideEffects":["*.css","*.less"] **```** * code split 1. 单入口 1. optimization 可以将node_modules中代码单独打包为一个chunk最终输出 自动提取多入口chunk中的公共文件,进行单独打包 ```webpack.config.js { ... optimization:{ splitChunks:{ chunks:'all' } } } ``` 2. import 语法 ```js // 动态导入语法(ES10语法):能将文件单独打包,返回一个Promise import('./src/test.js') // 动态导入并分包 import(/*webpackChunkName:'test'*/'./test') ``` 2. 多入口 * Object 几个入口就输出几个chunk,输出几个bundle ```webpack.config.js { entry:{ main:'./src/js/index.js', test:'./src/js/test.js' } } ``` * Array 所有入口文件最终只会形成一个chunk文件,输出一个bundle. 用途:在HMR功能中让html热更新生效 { entry:['./src/js/index.js','./src/js/test.js'] } * 懒加载 当文件需要使用时才加载 ``` import(/* webpackChunkName:'chunkname' /*'./filepath') ``` * 预加载 等其他资源加载完毕,浏览器空闲了再偷偷加载 ``` import(/* webpackPrefetch:true */'./test') ``` * PWA: 渐进式网络开发应用程序(离线可访问) 依赖于 workbox-webpack-plugin 插件 ```workbox-webpack-plugin { plugins:[ new workboxWebpackPlugin({ /* 1.帮助serviceWorker快速启动 2.删除旧的serviceWorker 生成一个 serviceWorker 配置文件 */ clientsClaim:true, skipWaiting:true }) ] } ``` ```index.js // index.js // 兼容性处理 if('serviceWorker' in navigator){ window.addEventListener('load',()=>{ navigator.serviceWorker .register('/service-worker.js) .then(()=>{ console.log('sw注册成功') }) .catch(()=>{ console.log('sw注册失败') }) }) } ```