一、使用webpack的原因
原生浏览器,不能很好的识别 ES6 以及更高版本中 ES moudule 模块引入方式。代码中使用 ES moudule ,可以通过webpack进行打包编译成浏览器识别的语法。
webpack同样可以识别,CommonJS模块引入规范、CMD、AMD等等。
webpack,是一个模块打包工具。
二、webpack初使用
1、安装webpack、webpack-cli
2、安装webpack成功后,执行webpack -v 失败。
原因:一般,webpack是安装在当前项目下。但是执行webpack -v 时,node会全局目录找,所以找不到。
方法:既然当前目录下安装了,当前目录下支持npx查看。 npx webpack -v
3、npx webpack 命令相关
(1)、webpack.config.js是默认配置文件。执行npx webpack,默认执行执行npx webapck --config webpack.config.js
(2)、如果使用非默认配置文件命名的文件,则使用npx webpack --config webpackconfig.js
4、node->package.json->scripts下命令讲解
"scripts": {"bundle": "webpack"}
执行npm run bundle时,会在当前项目目录中选择webpack。效果如同npx webpack
5、webpack打包输出注意点
chunk Names为entyr默认的main字段。
entry: {main: './src/index.js'}
Built at: 2019-06-08 15:58:36
Asset Size Chunks Chunk Names
bundle.js 70.4 KiB 0 [emitted] main
Entrypoint main = bundle.js
6、import引入js、css、图片等文件时,必须用相对路径或者绝对路径,否则报错。
三、webpack核心概念讲解
1、loader是什么?
webpack 可以使用 loader 来预处理文件。这允许你打包除 JavaScript 之外的任何静态资源。你可以使用 Node.js 来很简单地编写自己的 loader。
2、打包文件
file-loader与url-loader的区别:url-loader可根据文件大小,自动生成文件到dist/main.bundle.js或生成到dist目录中。
3、打包样式
loader加载顺序:从后到前
(1)、css-loader:合并css文件
了解css的模块化打包:避免全局污染,样式只针对当前文件有效。
模块化打包涉及到的参数:
importLoaders:(number)
moudle:(bunble)
(2)、style-loader:将样式挂载到dom上
(3)、sass-loader:
(4)、less-loader:
(5)、postcss-loader:
4、插件 plugins
(1)、autoprefixer:自动添加厂商前缀
(2)、html-webpack-plugins:自动生成打包后js文件的依赖html,并将js注入。
(3)、clean-webpack-plugin:每次打包之前,先默认清空dist目录下的依赖文件。
5、entry与output基础配置
多个entry入口和多个output输出的配置
publicPath:打包后,引入外部cdn资源
6、sourceMap配置
解决源代码和目标生成代码直接的映射关系。
development模式下,sourceMap默认开启
最佳实践推荐:
development下,devtool:cheap-module-eval-source-map
production下,cheap-module-source-map
7、使用webpackDevServer提升开发效率
webpack最基础的打包监听写法:scripts:{"bundle": "webpack --watch"},此功能不够全,使用webpackDevServer
webpackDevServer:webpack-dev-server 为你提供了一个简单的 web server,并且具有 live reloading(实时重新加载) 功能。
webpack-dev-middleware:是一个封装器(wrapper),它可以把 webpack 处理过的文件发送到一个 server。webpack-dev-server 在内部使用了它,然而它也可以作为一个单独的 package 来使用,以便根据需求进行更多自定义设置。
8、HOT Module Replacement 热模块更新(HMR)
模块热替换(hot module replacement 或 HMR)是 webpack 提供的最有用的功能之一。
它允许在运行时更新所有类型的模块,而无需完全刷新。(css:css-loader内置了HMR,自动只更新修改的css,其他不更新,所以不刷新页面。js:js没有相关模块内置,需要手动配置,)注:此功能对css友好,js不友好。因为js需要做许多配置,css不需要。
9、使用Babel处理ES6语法
babel使用的两种方式:
(1)编写.babelrc文件 (.babelrc中presets的执行顺序,也是从下到上)
(2) webpack.config.js中编写
npm install --save-dev babel-loader @babel/core //webpack和babel连接使用
npm install @babel/preset-env --save-dev //基础语法转换
npm install --save @babel/polyfill //高级语法注入
引入框架时,用@babel/plugin-transform-runtime处理
10、webpack实现对react框架代码的打包
npm install --save-dev react
npm install --save-dev react-dom
npm install --save-dev @babel/preset-react
{"presets": ["@babel/preset-react"]}
四、webpack高级概念 讲解
1、tree shaking
它依赖于 ES2015 模块语法的 静态结构 特性,例如 import 和 export
mode: 'development',
optimization: {
usedExports: true
}
{
"name": "your-project",
"sideEffects": false //可使用数组,提示webpack哪些不需要删除。css文件,不需要删除,使用数组"sideEffects": ["*.css"]
}
mode:"development"下,无用代码依然存在,但会清楚表明哪些用了,哪些没用。便于开发嘛。
mode:"producton"下,无用代码会被删除,因为上线了嘛。
2、development 和 production模式的区分打包
development(开发环境) 和 production(生产环境)这两个环境下的构建目标存在着巨大差异。
在开发环境中,我们需要:强大的 source map 和一个有着 live reloading(实时重新加载) 或 hot module replacement(热模块替换) 能力的 localhost server。
而生产环境目标则转移至其他方面,关注点在于压缩 bundle、更轻量的 source map、资源优化等,通过这些优化方式改善加载时间。
由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置。
npm install --save-dev webpack-merge
"scripts": {
"start": "webpack-dev-server --open --config webpack.dev.js", //开发环境使用
"build": "webpack --config webpack.prod.js" //生成环境打包使用
},
3、webpack和code splitting(代码分割)
代码分离是 webpack 中最引人注目的特性之一。此特性能够把代码分离到不同的 bundle 中,然后可以按需加载或并行加载这些文件。代码分离可以用于获取更小的bundle,以及控制资源加载优先级,如果使用合理,会极大影响加载时间。
代码分割,和webpack无关
引入文档解释:
常用的代码分离方法有三种:
入口起点:使用 entry 配置手动地分离代码。 //手动配置
防止重复:使用 SplitChunksPlugin 去重和分离 chunk。 //使用webpack方式1
动态导入:通过模块中的内联函数调用来分离代码 //使用webpack方式2
webpack中,实现代码分割的两种方式:
方式1、同步代码:只需要在webpack.config.js中,使用optimization.splitChunks 配置选项的配置即可。此配置方式很智能,会自动识别第三方库,并将第三方库独立打包。
方式2、异步代码(import):异步代码,无需做任何配置,会自动进行代码分割,放置到新的文件中。异步代码实现时,由于 import() 会返回一个 promise,因此它可以和 async 函数一起使用。但是,需要使用像 Babel 这样的预处理器和 Syntax Dynamic Import Babel Plugin。此配置方式也很智能,会自动识别第三方库,并将第三方库独立打包。
所有做的一切,都是为了提高页面速度。
4、splitChunksPlugin 配置参数详解
SplitChunksPlugin 为开箱即用,对用户友好。
5、Lazy Loading 懒加载 和 chunk
懒加载或者按需加载,是一种很好的优化网页或应用的方式。这种方式实际上是先把你的代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。
懒加载和webpack关系不大,
懒加载,其实就是通过ES Moudle 的import异步加载模块的功能。通过es7中的异步函数 async function(){},也可以实现懒加载。
6、webpack的打包分析工具使用:Preloadin、Prefetching
在声明 import 时,使用下面这些内置指令,可以让 webpack 输出 "resource hint(资源提示)",来告知浏览器:
prefetch(预取):将来某些导航下可能需要的资源
preload(预加载):当前导航下可能需要资源
7、css文件代码分割
它建立在新的Webpackv4功能(模块类型)之上,需要Webpack4才能工作。
这个插件应该只在没有style-loader的生产版本上使用,尤其是在您希望开发HMR的情况下。
MiniCssExtractPlugin,此插件不支持HMR,所以只能用在线上环境。
npm install --save-dev mini-css-extract-plugin
要缩小输出,请使用类似optimize-css-assets-webpack-plugin的Webpack的插件。设置optimization.minimizer将覆盖Webpack提供的默认值,因此请确保还指定一个JS minimizer:
8、webpack与浏览器缓存(caching)
clients(通常是浏览器)将访问该服务器以获取站点及其静态资源,最后一步可能很耗时,这就是为什么浏览器使用一种称为缓存的技术。这允许站点以更少不必要的网络流量更快地加载。
我们可以使用output.filename替换设置来定义输出文件的名称。Webpack提供了一种方法,可以使用名为substitutions的带括号字符串来模板化文件名。[ContentHash]替换将根据资产的内容添加唯一的哈希。当资产的内容更改时,[ContentHash]也将更改。
9、Shimming 的作用
Shimming(垫片)的概念很广泛,用到的也是方方面面。
Webpack编译器可以理解作为ES2015模块、CommonJS或AMD编写的模块。但是,某些第三方库可能需要全局依赖性(例如,jquery的$)。库还可以创建需要导出的全局,在这里Shimming开始发挥作用。
用到的场景:
(1)Jquery中的$
(2)polyfill,浏览器中使用更高级的ES6/7的语法。
这种方式违背了webpack的模块化开发,所以,能不用就不要用。
10、环境变量的使用方法
想要消除 开发环境 和 生产环境 之间的 webpack.config.js 差异,你可能需要环境变量(environment variable)。
五、webpack实战配置案例 讲解
1、Authoring Library
除了应用程序,Webpack还可以用于捆绑JavaScript库。
通过npm创建一个功能的js库,上传发布至npm,供他人使用。
npm publish
npm unpublish --force
"main": "dist/webpack-numbers.js" //package.json文件中用于发布包时的入口路径
2、PWA的打包配置
其实就是通过 Service Workers,当服务器宕机后,client端能够利用缓存继续访问的技术。(前提你的浏览器支持SW)
npm install workbox-webpack-plugin --save-dev
3、TypeScript的打包配置
首先运行以下命令安装TypeScript编译器和loader:
npm install --save-dev typescript ts-loader
4、WebpackDevServer实现请求转发
规范、方便,开发、线上环境接口配置
5、WebpackDevServer解决单页面路由问题
historyApiFallback //解决页面路由跳转失败的问题
此配置只用在本地开发环境,发布线上环境后,需要后端人员配置左下页面路由跳转。
6、EsLint 在Webpack 配置
EsLint和webpack没关系。
可组装的JavaScript和JSX检查工具
使用方式:
(1)使用EsLint规范代码,开发工具最好用Visual Studio Code编辑器。(推荐)
(2)git提交仓库之前,利用git钩子函数检测,不方便。
7、webpack性能优化(尽可能的降低打包速度)
(1)跟上技术迭代(node/npm/yarn)
(2)在尽可能少的模块上应用loader
使用include/exclude
(3)、Plugin尽可能精简并确保可靠
例如:dev环境下,代码压缩就可以不用。
(4)resolve参数合理配置
这些选项更改模块的解析方式。Webpack提供了合理的默认值,但可以详细更改解析。查看模块分辨率,了解分解器如何工作的更多说明。
说白了,也就是导入文件时,能后通过webapck的resolve配置,减少导入模块的路径。
(5)、使用DllPlugin提供提高打包速度
(6)、控制包文件大小
(7)、thread-loader,parallel-webpack,happypack多进程打包
(8)、合理使用sourceMap
(9)、结合stats分析打包结果
(10)、开发环境内存编译
(11)、开发环境无用插件剔除