基础概念
通过官网的指引安装好webpack,在项目根目录添加 webpack.config.js
的文件.
webpack.config.js
遵循的是 commonJS
规范,依次文件采用 module.exports={[key]:[value]}
的方式,来暴露具体的配置。
一个基本的webpack配置如下
1 | module.exports = { |
Entry
指定webpack,打包的起始文件,根据此文件分析构建依赖关系图。
入口文件,可配置一个,也可以 {[key]:[value]}
的形式配置多个
Output
指示webpack打包后的资源,输出到哪里去,以及如何命名。
output的值是一个对象,指定了输出文件名,和文件路径,输出文件建议使用 path模块中的resolve即 resolve(__dirname,xxx)
在webpack中输出的文件名,如果你不想指定,可以取使用[hash].扩展名
的形式,webpack在输出的时候,会自动指定hash值。
Loader
Webpack去处理那些非Javascript
文件。(webpack本身只处理js和json数据)
对应webpack的字段是 module
,里面指定了webpack各种的loader配置。形如
1 | module: { |
rules中的每一个对象,对应着一个处理某个文件的模块,为了处理某种文件,我们需要配置,匹配这个文件的正则表达式,形如 test:/具体正则表达式/
,和通过 use:[loader-name]
的形式指定 多个loader,如:处理css 文件,我们需要 style-loader
和 css-loader
。甚至有时候use数组里面,不只是 各个loader的名称,可能还需要修改一些loader的配置,就会采取对象的形式指定loader,如给css添加兼容性处理的情景
同一文件各种loader的处理顺序是自下而上的,css文件配置如下,文件会先经过 css-loader
处理,再经过style-loader
处理。
1 | module: { |
上面引入的两种loader都是直接通过loader名称的形式引入的,按照对象的方式引入postcss-loader,对css做兼容性处理。
1 | { |
当然最后要注意的是,这些loader都不是webpack,内置的,而是需要 通过npm 安装。具体的插件安装可看官网。建议大家和webpack有关的都安装在 devDependencies
下 。
Plugins
各种功能强大的工具,包括打包优化和压缩,甚至可以重新定义环境中的变量。插件相比于Loader可以做很多比Loader功能更强大的事。
插件和loader相同的是都需要先npm安装,不同的是,loader不需要引入,但是要在use里面写一些配置。而插件则是通过,先require 引入某个插件,然后再在plugins,实例化引入的插件对象即可。如果需要修改插件的默认配置,在实例化的时候,以对象的形式传入即可。
html 模板插件使用如下
1 | const HtmlWebpackPlugin = require('html-webpack-plugin') |
Mode
模式分为 development
开发环境,production
生产环境。
这大概是webpack最简洁的配置了,在production
模式下,会自动开启压缩js代码和 tree shaking
。
在未来的 webpack5中,只有在 webpack.config.js
文件中指定一个mode,就可以使用,上面的 entry,output
等配置,都变成了默认配置。
webpack打包过程
- 指定入口文件 entry
- webpack会根据入口文件里面所有的依赖,形成依赖树,然后会根据依赖树中把所以需要的依赖引入,形成代码块(chunk),然后再根据不同的资源对应的loader,对代码块进行处理输出为
bundles
.
处理css、less
1 | npm install style-loader css-loader -D |
其中 css-loader 是为了把 css 文件变成commonJS模块,加载到JS中,style-loader是为了在JS解析的时候能创建style标签,把样式整合到style标签中,插入浏览器的head。
默认是有多少css,less 文件就会插入多少style标签,每个标签就是对应的css代码。
1 | npm install less-loader -D |
安装less-loader处理less文件,注意loader在代码里面配置顺序是固定的,less文件必须要经过less-loader处理,才能被css-loader识别,同理最后才能被style-loader处理。
1 | rules: [ |
把css,less文件提取合并,并且压缩一下形成单独的css,再通过link标签引入。目的是为了把css尽快的提供给浏览器,而不是放在js中,导致浏览器需要先解析js才能获取css,具体原因见博客~浏览器,需要使用插件 mini-css-extract-plugin
1 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') |
把css文件和less文件配置中的,style-loader都替换成 MiniCssExtractPlugin.loader
,在plugins中实例化插件并且制定输出文件路径,完整配置如下
1 | const { resolve } = require('path') |
压缩css,感觉就是去掉了css文件中的,空格注释,也可能去掉了一些写重复的样式吧,反正就是为了减少文件体积加快网络传输速度。需要用到插件optimize-css-assets-webpack-plugin
1 | npm install optimize-css-assets-webpack-plugin -D |
这个插件使用比较简单了,一样需要引入
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
1 | .... |
处理HTML、图片、其他静态资源
1 | npm install html-webpack-plugin -D |
处理HTML文件需要使用 html-webpack-plugin
,在plugins中实例化的时候,指定一下使用的模板,webpack会把输出的js通过script标签自动引入HTML中。
1 | // webpack处理 HTML |
处理图片资源的时候使用的是loader名称是url-loader
,没有photo-loader😁😁😁,当然还要下载file-loader,因为url-loader依赖于file-loader
1 | npm install file-loader url-loader -D |
具体配置如下,可以解决commonJS import 图片资源,和css,less文件中url里面引用图片资源的问题。
1 | { |
如果还要处理HTML模板中引入图片的问题还需要使用 html-loader
,
此时要注意修改一下之前url-loader的配置,因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs,解析时会出问题:[object Module],需要在url-loader配置文件中,关闭url-loader的es6模块化,使用commonjs解析
1 | npm install html-loader -D |
1 | { |
处理其他静态资源,比如字体图标文件等,需要安装file-loader,在之前安装url-loader的时候已经安装过file-loader了
1 | { |
css兼容性处理
面试的时候经常会被问到,浏览器兼容性问题,作为一个学生,目前我开发都是使用Chrome和Firefox,处理浏览器兼容性问题,也就是webpack配置一下。
兼容css需要用插件postcss-loader,和插件的的配置postcss-preset-env(当然也可采用,autoprefixer规则取代postcss-preset-env规则)
1 | npm install postcss-loader postcss-preset-env -D |
安装好插件,如果业务场景浏览器确定,可采用中 package.json
增加browserslist
,来确定具体浏览器,至于browserslist的配置文件可看github
其中development
,production
是指NodeJS环境(process.env.NODE_ENV
),默认是production,而非webpack指定的mode。
1 | { |
具体配置如下
1 | const miniCssExtractPlugin = require('mini-css-extract-plugin') |
devServer
配置devServer,相当于本地运行了一个NodeJS后来服务,需要安装插件webpack-dev-server
,此时webpack编译的结果不会输出在我们指定的目录下,因为dev-server不输出文件,可以想象成文件放内存中,node服务可以访问到,因此我们手动刷新浏览器可以看到正确结果。
1 | npm install webpack-dev-server -D |
1 | module.exports = { |
此时我建议在 package.json
的 script
脚本中写入两条脚本,分别用于之前的打包模式和开启devServer 模式
1 | { |
通过运行 npm run build
或者npm run build:prod
获取之前类似的输出,npm run dev
开启webpack服务,此时还不支持热更新和自动刷新浏览器,需要手动刷新,才能看到结果。
更多devServer看 官网配置
Javascript代码兼容性
前面配置了css代码的兼容性处理,但是JS代码其实更需要兼容,JS不兼容可能就是无法运行。处理JS兼容当然就是babel
家族。babel官网
1 | npm install @babel/cli @babel/core @babel/preset-env babel-loader -D |
在项目根目录编写 babel.config.js
文件,写入如下配置
1 | module.exports = { |
在webpack.config.js中用babel处理js
1 | module.exports={ |
上面的babel配置 (我用的是babel7的配置) 是我上次配置ts的,不知道会不会出错,应该没有问题, presets
里面指定了target
, core-js
部分没问题,应该就可以兼容ie。
我认为 webpack最好的教程是来源与官网,这是我看了官网和网上找的一些视频教程之后总结的一些基础操作,详细的配置可看 webpack官网~中文,本文中部分文字来源于尚硅谷的视频,感谢尚硅谷老师的分享。【这不是广告只是为了声明版权😂】
以上差不多就是 webpack的一些基本操作了,后面打算把webpack配置优化部分也补上,然后自己封装一个脚手架,再加上一些ESLint的配置,欢迎大家持续关注 http://lemonlife.top 最近有点忙/(ㄒoㄒ)/~~