0。介绍继续上一篇Webpack4教程从零开始。今天主要说说在写webpack配置的时候,如何优化打包后生成的在线代码。1.TreeshakingTreeshaking是一个术语,通常用来描述在JavaScript上下文中移除未引用的代码。它依赖于ES2015模块系统中的静态结构特性,例如导入和导出。配置:Modular语法使用ES2015模块化(注意babel不能将ES6模块化语法转成commonjs)use模式生产,UglifyJSPlugin会自动使用UglifyJSPlugin压缩js代码{test:/\.js$/,exclude:/node_modules/,use:{loader:"babel-loader",options:{presets:[['@babel/preset-env',{"modules":false//关闭babel将ES6模块转为commonjs,webpack自动带此功能}]]}}}这时候代码环境已经可以去掉未引用的代码了~2.延迟加载防止特定js文件一出现就加载下载babel相关的包npmi@babel/plugin-syntax-dynamic-import@babel/plugin-transform-runtime@babel/runtime-D@babel/plugin-syntax-dynamic-importallowsparsingimport()syntax@babel/plugin-transform-runtime用于语法转换@babel/runtime用于解决错误Modulenotfound:Error:Can'tresolve'@babel/runtime/regenerator',需要下载当前包,下载eslint相关包npmibabel-eslinteslint-config-airbnbeslint-plugin-importeslint-plugin-jsx-a11yeslint-plugin-react-Dbabel-eslint用于支持eslint不支持的语法或实验特性的配置eslint-config-airbnbairbnb,其他packages相关依赖eslint的package.json配置"eslintConfig":{"extends":"airbnb",//famouseslintstandard"parser":"babel-eslint",//替换eslint默认的解析库,支持import()等非标准化语法。"parserOptions":{"ecmaVersion":8,"sourceType":"module"},"rules":{"linebreak-style":[0,"error","windows"]//忽略换行错误CRLF},"env":{"browser":true//支持浏览器全局变量}},修改loader{test:/\.js$/,exclude:/node_modules/,use:{loader:"babel-loader",options:{presets:[...],plugins:["@babel/plugin-syntax-dynamic-import",//Resolveimport()[require.resolve("@babel/plugin-transform-runtime"),//帮助解析再生器错误{"absoluteRuntime":false,"corejs":false,"helpers":false,//只需要修改这个,其他都是默认配置,可以不加"regenerator":true,"useESModules":false}]]}}},修改outputoutput:{filename:'js/[name].[hash:8].js',//添加hash值实现静态资源的长期缓存chunkFilename:'js/[name].bundle.js',//非入口chunk的名称publicPath:'/'//所有输出资源的公共路径},useasyncfunctiongetComponent(){constelement=document.创建元素ent('div');/*webpackChunkName:"modulename"'modulepath'*/constmodule=awaitimport(/*webpackChunkName:"module2"*/'./module2');constPerson=module.default;const{姓名,年龄}=newPerson('jack',18);element.innerHTML=`名字:${name}年龄:${age}`;returnelement;}/*只有触发onclick事件才会动态加载module2文件执行代码*/document.getElementById('box1').onclick=()=>{getComponent().then((component)=>{document.body.appendChild(component);});};3、codesplit代码拆分,将常用代码提取到单独的模块中,方便缓存。Configureoptimization:{/*runtimeChunk设置为true,webpack会将所有的chunk文件名存储在一个单独的chunk中,这样更新一个文件只会影响它所在的??chunk和runtimeChunk,避免引用这个chunk的文件发生变化发生了。*/runtimeChunk:true,splitChunks:{chunks:'all'//默认entrychunk不会被拆分,配置成all,就这样}}因为是单entry文件配置,所以没有考虑multi-条目情况,多个条目应分别处理。4.缓存哈希:哈希是整个编译过程中产生的总哈希值,而不是单个文件的哈希值。对项目中的任何文件进行更改都会导致哈希值发生变化。占位符[hash]一直存在,但是我们不想修改一个文件就改变所有输出文件的hash,这样就不能使用浏览器缓存了。所以这个[hash]没有多大意义。chunk:代码中引用的文件(js、css、images等)会根据配置组合成一个或多个包。我们称一个包为块。每个块包含多个模块。不管是不是js,webpack都会把导入的文件当做一个模块。chunkhash:这个chunk的hash值,这个值也会随着文件改变而改变。使用[chunkhash]作为文件名可以防止浏览器读取旧的缓存文件。配置插件/*以使用文件路径的哈希值作为moduleId。虽然我们使用[chunkhash]作为chunk的输出名称,但仍然不够。因为块中的每个模块都有一个id,webpack默认使用一个递增的数字作为moduleId。如果引入新文件或删除文件,其他文件的moduleId也可能发生变化,受影响模块所在chunk的[chunkhash]也会发生变化,导致缓存失效。所以使用文件路径的hash作为moduleId可以避免这个问题。*/newwebpack.HashedModuleIdsPlugin()修改文件输出路径js/[name].[hash:8].js-->js/[name].[chunkhash:8].jscss/[name].[hash:8.css-->css/[name].[chunkhash:8].css5,progressivewebapplicationProgressivewebapplication(PWA),是一种类似于原生应用(nativeapp)网络应用(webapp)的体验。PWA可以用于很多事情。其中最重要的是应用程序在离线时继续运行的能力。下载插件npmiworkbox-webpack-plugin-D导入插件constWorkboxPlugin=require('workbox-webpack-plugin');配置插件newWorkboxPlugin.GenerateSW({//这些选项帮助ServiceWorkers快速启用//不允许任何遗留的“旧”ServiceWorkers//有关更多配置详细信息,请参阅:https://developers.google.com/web/tools/workbox/modules/workbox-webpack-pluginclientsClaim:true,skipWaiting:true,importWorkboxFrom:'local',//打包到本地,默认值为'cdn'访问国外CDN需要翻墙包括:[/\.html$/,/\.js$/,/\.css$/],//包含资源exclude:[/\.(png|jpg|gif|svg)/]//排除资源})入口文件配置.log('SWregistered:',registration);}).catch((registrationError)=>{console.log('SW注册失败:',registrationError);});});}运行命令npmrunbuildserve-sdist此时可以在浏览器控制台看到serviceworker注册成功。您可以尝试关闭服务器或断开网络。这时候神奇的事情发生了,我们的网页依然可以正常浏览~这就是PWA的神奇之处,还有PWA的详细应用,可以点开这篇文章看看~点击查看本文源码未完待续~
