webpack 配置二
模式:
webpack4中可以直接指定模式,以现实不同环境对打包代码做不同的处理,2而webpack2,3中是通过插件进行代码压缩以及改变环境变量的
module.exports = { mode: 'development', }; //相当于 module.exports = { devtool:'eval', plugins: [ new webpack.NamedModulesPlugin(), new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }) ] }
开启开发模式对开发友好,不会对代码进行压缩
module.exports = {
mode: 'production',
};
//相当于
module.exports = {
plugins: [
new UglifyJsPlugin(/*...*/),
new webpack.DefinePlugin({ //改变环境变量
"process.env.NODE_ENV": JSON.stringify("production")
}),
new webpack.optimize.ModuleConcatenationPlugin(),//预编译所有模块到一个闭包中,提升你的代码在浏览器中的执行速度。
new webpack.NoEmitOnErrorsPlugin()//在编译出现错误时,使用 NoEmitOnErrorsPlugin
来跳过输出阶段。这样可以确保输出资源不会包含错误。
]
}
生产模式不用对开发友好,只需要关注打包的性能和生成更小体积的bundle
loader:
css-loader和style-loader:
css-loader和style-loader从名称看起来功能很相似,然而两者的功能有着很大的区别,但是他们经常会成对使用;安装方法:
npm i -D css-loader style-loader
css-loader
解释(interpret) @import
和 url()
,会 import/require()
后再解析(resolve)它们。
css-loader解析css文件以字符串的形式,变成common.js插入到js文件中
style-loader用来将css-loader生成的样式表通过<style>标签
,插入到页面header中去。
sass-loader和less-loader:
用来处理sass和less样式的。安装方法:
npm i -D sass-loader less-loader node-sass less
配置:
{ //其他配置 rules: { test: /\.scss$/, use: [{ loader: 'style-loader' }, { loader: 'css-loader' },{ loader: 'sass-loader' }] },{ test: /\.less$/, use: [{ loader: 'style-loader' }, { loader: 'css-loader' },{ loader: 'less-loader' }] } }
postcss-loader:
提供了很多对样式的扩展功能
npm i -D postcss-loader
配置:
rules: [{ test: /\.scss$/, use: [{ loader: 'style-loader' }, { loader: 'css-loader' }, { loader: 'postcss-loader' },{ loader: 'sass-loader' }] },{ test: /\.less$/, use: [{ loader: 'style-loader' }, { loader: 'css-loader' }, { loader: 'postcss-loader' },{ loader: 'less-loader' }] }]
因为postcss主要功能只有两个:第一就是把css解析成JS可以操作的抽象语法树AST,第二就是调用插件来处理AST并得到结果;所以postcss一般都是通过插件来处理css,并不会直接处理,所以我们需要先安装一些插件:
npm i -D autoprefixer cssnano
autoprefixer是一个兼容浏览器,给一些css加上前缀的插件
cssnano是一个压缩和优化css的插件
在项目根目录新建一个.browserslistrc
文件。
> 0.25% last 2 versions
或者在package.json加入
"browserslist": [ "defaults", "not ie < 11", "last 3 versions", "> 0.2%", "iOS 7", "last 3 iOS versions" ]
我们将postcss的配置单独提取到项目根目录下的postcss.config.js
:
module.exports = { plugins: [ //自动添加前缀 require('autoprefixer'), //优化合并css require('cssnano')(), ] }
babel-loader:
用以处理es6语法,将其编译为浏览器可运行的js语法,只能转换最基本的语法,如promise等不能转化
安装:
npm install -D babel-loader @babel/core @babel/preset-env
配置:
{ test: /\.js$/, use: { loader: "babel-loader", options: { presets: ["@babel/preset-env"], }, }, },
如需完全兼容需安装
@babel/polyfill,其使用方式直接在页面引入
import "@babel/polyfill";
其缺点打包的体积过大,里面包含了很多兼容性处理的代码
为了更好的优化代码,我们一般会对代码进行按需引入,那么@babel/polyfill也是可以对代码进行处理限制,接下来讲讲,怎么配置
首先要讲讲配置中用的几个参数:
@babel/polyfill 和 @babel/preset-env 的关系
@babel/preset-env 中与 @babel/polyfill 的相关参数有 targets 和 useBuiltIns 两个
targets: 支持的目标浏览器的列表
useBuiltIns: 参数有 “entry”、”usage”、false 三个值。默认值是false,此参数决定了babel打包时如何处理@babel/polyfilll 语句。
“entry”: 会将文件中 import‘@babel/polyfilll’语句 结合 targets ,转换为一系列引入语句,去掉目标浏览器已支持的polyfilll 模块,不管代码里有没有用到,只要目标浏览器不支持都会引入对应的polyfilll 模块。
“usage”: 不需要手动在代码里写import‘@babel/polyfilll’,打包时会自动根据实际代码的使用情况,结合 targets 引入代码里实际用到 部分 polyfilll 模块
false: 对 import‘@babel/polyfilll’不作任何处理,也不会自动引入 polyfilll 模块。
需要注意的是在webpack打包文件配置的entry 中引入的 @babel/polyfill 不会根据useBuiltIns 配置任何转换处理。
Browserslist集成
对于基于浏览器或Electron的项目,我们建议使用.browserslistrc
文件来指定目标。您可能已经有了此配置文件,因为该文件已被生态系统中的许多工具所使用,例如autoprefixer,stylelint,eslint-plugin-compat等。
默认情况下,除非设置了target或ignoreBrowserslistConfig选项,否则@babel/preset-env
将使用browserslist配置源
配置如下:
{ test: /\.js$/, exclude: /node_modules/, use: { loader: "babel-loader", options: { presets: [ [ "@babel/preset-env", { //按需加载 useBuiltIns: "usage", //指定版本 corejs: { version: 3, proposals: true, }, //指定兼容的浏览器 targets: { ie: 10, chrome: "60", firefox: "60", safari: "10", }, }, ], ], }, }, },
参考资料:https://blog.hhking.cn/2019/04/02/babel-v7-update/
babel官网:https://babeljs.io/docs/en/next/babel-preset-env
url-loader与file-loader
npm i file-loader url-loader -D
配置:
test: /\.(png|jpg|gif|jpeg|webp|svg|eot|ttf|woff|woff2)$/, exclude: /node_modules/, use: { loader: 'url-loader', options: { //10k limit: 10240, //生成资源名称 name: '[name].[hash:8].[ext]', //生成资源的路径 outputPath: 'imgs/' } }
html-loader
处理html中的img,配置
{ test: /\.html$/, //处理html的img,采用的是commom.js解析方式 loader: "html-loader", },
如果用了html-loader,就要改变url-loader options的esModule,如下修改
{ test: /\.(png|jpg|gif|jpeg|webp|svg|eot|ttf|woff|woff2)$/, exclude: /node_modules/, use: { loader: "url-loader", options: { //10k limit: 10240, //生成资源名称 name: "[name].[hash:8].[ext]", //生成资源的路径 outputPath: "imgs/", //默认是用es6模块化解析,而html是用commom.js解析方式 esModule: false, } },
开发环境,我们想要的效果是写完代码就看到效果,而webpack-dev-server就很好的提供了一个简单的web服务器,能够实时重新加载。
安装:
npm i -D webpack webpack-dev-server
配置:
devServer: {
//启动服务器端口
port: 9000,
//默认是localhost,只能本地访问
host: "0.0.0.0",
//自动打开浏览器
open: false,
//启用模块热替换
hot: true,
//启用gzip压缩
compress: true
},
plugins: [
//热更新插件 new webpack.HotModuleReplacementPlugin({ })
]
在开发中,还有一个最重要的环节就是调试,到这一步我们发现我们所得的代码都是编译过的,与我们源代码差异很大,所以,我们需要将编译后的代码映射回源码;
而devtool很好的解决了这个问题,我们可以配置:
devtool: 'cheap-module-eval-source-map',
当然,他也有很多的参数,来得到不一样的效果
至此,webpack开发环境,我们就搭建完成了