1.mode属性:
webpack需要设置mode属性用来指明是开发环境还是生产环境,可以是development或production,例如: webpack --mode development
webpack针对开发模式提供的特性: 浏览器调试工具、注释、开发阶段的详细错误日志和提示、快速和优化的增量构建机制
webpack针对生产模式提供的特性:开启所有的优化代码、更小的bundle大小、去除掉只在开发阶段运行的代码. Scope hoisting(将多个bunnd.js放到同一闭包里面,加快代码运行速度)和Tree-shaking(进入未使用的模块给它去掉,减小整个bunnd.js的大小)
2.插件和优化:
webpack4删除了CommonsChunkPlugin插件,它使用内置API optimization.splitChunks和optimization.runtimeChunk,这意味着webpack会默认为你生成共享的代码块。
其他插件的变化:
NoEmitOnErrorsPlugin废弃–>使用optimization.noEmitOnErrors替代
ModuleConcatenationPlugin 废弃–>使用optimization.concatenateModules替代
NamedModulesPlugin 废弃–>使用optimization.namedModules替代
uglifyjs-webpack-plugin升级到了v1.0版本
3.开箱即用WebAssembly:
WebAssembly(wasm,汇编,允许在web上执行二进制,对js性能的补充。)会带来运行时性能的大幅度提升,由于在社区的热度,webpack4对它做了开箱即用的支持。你可以直接对本地的wasm模块进行import或者export操作,也可以通过编写loaders来直接import C++、C或者Rust。
4.支持多种模块类型共五种:
javascript/auto: 在webpack3里,默认开启对所有模块系统的支持,包括CommonJS、AMD、ESM。
javascript/esm:只支持ESM这种静态模块
javascript/dynamic:只支持CommonJS和AMD这种动态模块
json:只支持JSON数据,可以通过require和import来使用
webassembly/experimental:只支持wasm模块,目前处于试验阶段
5.OCJS
0CJS的含义是0配置,webpack4受Parcel打包工具启发,尽可能的让开发者运行项目的成本变低。为了做到0配置,webpack4不再强制需要webpack.config.js 作为打包的入口配置文件了,它默认的入口为’./src/‘和默认出口’./dist’,对小项目而言是福音。
6.新的插件系统
webpack4对插件系统进行了不少修改,提供了针对插件和钩子的新APl。变化如下:
所有的hook由hooks对象统一管理,它将所有的hook作为可扩展的类属性。·
当添加插件时,必须提供一个插件名称。
开发插件时,可以选择sync/callback/promise作为插件类型。
可以通过this.hooks = { myHook: new SyncHook(…)}来注册hook了。
注意:当使用webpack4时,确保使用Node.js的版本>=8.9.4。因为webpack4使用了很多JS新的语法,它们在新版本的v8里经过了优化。
7.安装webpack
npm install webpack webpack-cli -g
// -g这里表示全局安装,也可以在自己项目中安装,将-g去掉,每个项目配置自己独有的打包模块,推荐全局安装,以节省自己内存空间,不过别人下载你的项目后需要知道webpack版本号,否则可能会报版本问题的bug
8.webpack基本使用:
webpack最基本的使用就是一个输入文件一个输出文件,在项目中输入文件一般是main.js,输出文件是webpack打包后的文件,这个文件名通常在webpack配置文件中配置好就行,当然也可以通过webpack打包输出文件,其命令:webpack main.js -o bundle.js ,其中-o表示输出,后面的是文件名,不过通常情况下这些配置都是配置在配置文件中的,这样我们只需要简单的命令即可完成打包,如:
webpack.config.js基本配置:
// 1.引入path包,webpack5中输出文件要求绝对路径,因此这需要引入path模块
const path = require('path')
module.exports = {
// 2.打包入口文件
entry: './src/main.js',
// 3.打包输出文件
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
// 4.开发环境下,建议打开该选项
devtool: 'eval-source-map',
}
package.json配置打包命令(webpack4以上强制要求指明打包环境,因此后面需要–环境):
// 生产环境
"build": "webpack --mode=production"
// 开发环境
"dev": "webpack --mode=development"
// 热更新启动项目
"server": "webpack-dev-server"
提示: 有的时候会有多个入口文件,此时可以配置多个入口文件,输出文件则要配置成灵活的,如:
module.exports = {
// 入口文件可以配置多个,此时可以打包出多个打包文件
entry: {
main: './src/main.js',
utils: './src/utils.js'
},
// 多个打包文件命名需要写成动态命名,name实际是入口配置中对象的key
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].bundle.js'
}
}
loaders:
loaders是将TypeScript、Less、Sass、files、JSON、Transpiling(将其他各种语言转换为js)等语言处理成前端可认识的工具,loaders是一类工具,使用某个工具时需要先npm下载
url-loader: 当文件的大小小于某个值时,将文件转换为base64的格式,一般代替精灵图(小图标推荐base64格式,减少请求,因为base64位图片是以代码的形式直接写在文件中)
babel-loader:将es6-es7等高级语法代码转换为es5,它需要用到@babel/preset-env、@babel/plugin-proposal-object-rest-spread 等组件,使用时也要下载,@babel/plugin-transform-react-jsx:处理react的组件:npm i @babel/plugin-transform-react-jsx -D ,-D表示开发环境才会用到
插件:
一类打包对代码处理的工具,下面介绍几个常用插件:
mini-css-extract-plugin: webpack默认将转换后的css代码是放到js文件的,这样会导致js文件很臃肿,那么可以使用mini-css-extract-plugin将css代码抽离成为css代码文件,此模块需要单独下载。
DefinePlugin: 用来做定义的,定义一些ip等,如生产环境ip和开发环境ip的定义等,此插件从webpack模块解构出来即可。
html-webpack-plugin:用来生成html文件的插件,此插件需要安装
devServer: 热替换,在代码被修改后会自动热更新到浏览器,无需重新刷新浏览器,此插件需要单独安装,npm i webpack-dev-server -g ,注意是webpack-dev-server这个包
webpack.config.js 配置文件:
// 7-1: 引入mini-css-extract-plugin插件:
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 7-2: 解构定义配置插件:
const { DefinePlugin } = require('webpack')
// 7-3: 引入生成html文件的插件:
const htmlWebpackPlugin = require('html-webpack-plugin');
// 1.引入path包,webpack5中输出文件要求绝对路径,因此这需要引入path模块
const path = require('path')
module.exports = {
// 2.打包入口文件
entry: './src/main.js',
// 3.打包输出文件
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
// 4.开发环境下,建议打开该选项
// devtool: 'eval-source-map',
// 5.配置打包环境:production生产环境、development开发环境,一般在package.json文件中配置命令即可
mode: 'production',
// 6.配置loader:
module: {
rules: [
// A.将图片文件处理为base64位文件:npm i url-loader -S ,将url-loader先安装到本地,-S表示同时需要记录在package.json中
// 此时去打包提示需要安装file-loader,原因是图片属于文件类型,因此还需要file-loader,继续npm i file-loader -S安装,后面其它loader安装方式一样,我就不重复了
{
test: /\.(jpg|svg|png|gif)$/,
use: [
{
loader: 'url-loader',
options: {
// 默认为true,即使用es6模块化;设为false,即使用commonJs模块语法
esModule: false,
outputPath: 'images',
limit: 100*1024, // 小于100kb的图片转为base64
name: '[hash].[ext][query]', // 自定义输出文件名
// webpack5使用旧的assets loader(如file-loader/url-loader)
// 可以加'javascript/auto'来解决图片无法生成images文件夹(目标文件夹)
type: 'javascript/auto'
}
}
]
},
// B.处理js、react高级语法:
{
test: /\.(m?js|jsx)$/, // 处理js,和react文件
exclude: /(node_modules|bower-components)/, // 忽略node_modules等文件
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env','@babel/preset-react'], // @babel/preset-env核心对js高级语法解析的工具,@babel/preset-react解析react语法
plugins: ['@babel/plugin-proposal-object-rest-spread'] // 处理react的工具
}
}
},
// C.处理sass:
{
test: /\.scss$/,
use: [
// 以下是未使用MiniCssExtractPlugin插件配置:
// "style-loader",
// "css-loader",
// "sass-loader"
// 使用MiniCssExtractPlugin插件配置:
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader"
]
}
]
},
// 7.插件:
plugins: [
// 7-1.从js文件抽离css代码到css文件:
new MiniCssExtractPlugin({
filename: 'css/[name].css',
chunkFilename: '[id].css',
}),
// 7-2.定义配置,如不同环境的ip地址:DefinePlugin需要先从webpack中解构出来
new DefinePlugin({
// 这里定义的:SERVICE_URL可以在项目其他文件中使用
'SERVICE_URL':JSON.stringify('https://blog.csdn.net/weixin_46758988')
}),
// 7-3:生成html文件:htmlWebpackPlugin默认可以什么也不配置,如果想要生成自定义html文件,那么就要对其配置:
new htmlWebpackPlugin({
title: 'my-app', // 用来设置网站标题
filename: 'index.html', // 设置文件名,默认就为:index.html
template: './src/index.html', // 默认html模板,在这个文件可以引入项目所依赖的其他文件
})
],
// 8.热替换:
devServer: {
// contentBase: path.join(__dirname,'dist'), // 启动文件位置,版本问题,开启会报bug
compress: true, // 是否压缩代码
port: 9000, // 端口
// hot: false // 热替换,false表示热替换,true表示不热替换
},
// 9.webpack自身配置:
// configureWebpack: {
// // 是否开启代码性能提示:有些文件大小超过webpack默认的配置大小会报警告
// performance: {
// hints: false, // 关闭,其值还可以是:warning表示警告:
// // 入口起点的最大体积
// maxEntrypointSize: 50000000,
// // 生成文件的最大体积
// maxAssetSize: 30000000,
// // 只给出 js 文件的性能提示
// assetFilter: function(assetFilename) {
// return assetFilename.endsWith('.js');
// }
// },
// }
}
// module.exports = {
// // 入口文件可以配置多个,此时可以打包出多个打包文件
// entry: {
// main: './src/main.js',
// utils: './src/utils.js'
// },
// // 多个打包文件命名需要写成动态命名,name实际是入口配置中对象的key
// output: {
// path: path.resolve(__dirname, 'dist'),
// filename: '[name].bundle.js'
// }
// }
提示:本文图片等素材来源于网络,若有侵权,请发邮件至邮箱:[email protected]联系笔者删除。
笔者:苦海