Webpack5
Webpack是一款模块打包工具,能把多个文件打包成一个或几个文件,它不仅能打包JS文件, 还能打包css, image等静态资源。当然,在默认情况下,它只打包JS文件和JSON文件,因为它只认识JS文件和JSON文件。
mkdir webpack-demo
cd webpack-demo
npm init -y
创建webpack-demo项目,并创建package.json 文件,管理项目依赖和脚本命令。npm install webpack webpack-cli --save-dev,安装webpack。webpack4把webpack命令抽离出来,形成了一个单独的包webpack-cli ,安装它,才能在命令行中使用webpack命令。为什么要单独形成一个包呢?因为webpack-cli 还提供了两个其它的功能,init 和 migrate命令,使我们快速创建webpack配置和提供升级迁移。不过这两个基本不用,了解一下就可以了。只要记住安装webpack的同时安装上webpack-cli就可以了。
mkdir src 存放源文件,touch src/index.js, touch src/component.js 文件,component.js 文件
export default (text = 'hello world') => {
const element = document.createElement('div');
element.innerHTML = text;
return element;
}
index.js 文件
import component from './component';
document.body.appendChild(component());
npx webpack 生成了dist 目录,打包成功了。npm5之后,npx可以执行命令。webpack是怎么打包的?不是要写配置文件吗?webpack4提供零配置,没有写配置文件,也能打包。webpack进行打包的时候,没有配置文件,默认入口是src/index.js,默认输出目录是dist,文件名是main.js. 但有一个WARNING,
没有设置mode,webpack4 提供了一个mode 配置项 ,用什么模式进行打包,模式不同,打包后的文件内容不同。它有三个选项development, production, none. 看名字也就知道了,development 开发模式,这种模式下有利于开发,production,生产模式,这有利于生产环境。none就是什么都不做,很少用到它。mode 可以在命令行进行配置, npx webpack --mode development ,查看一下dist/main.js,没有压缩。npx webpack --mode produciton,生成的代码压缩了。开发模式下,没有压缩,而生产模式下,压缩代码。和我们想的是一样的,线上的代码都是压缩代码,开发肯定不压缩,要不然没有调试。 随着指令越来越长,手动输入就比较麻烦了,可以使用npm run 命令,在package.json的scripts的字段中
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
npm run build或npm run dev都能打包成功。怎么验证一下打包后的文件是正确的?手动建一个html 文件,script 引入 dist/main.js,这肯定没有问题。但有了webpack后,能不能自动化?webpack有一个插件html-webpack-plugin,它会创建html文件,并自动引入打包后文件。npm i html-webpack-plugin -D,不过,这要写webpack配置文件了,零配置此时无能为力了。webpack有production和development两种mode,这也提醒我们要针对不同的环境,提供不同的配置,一种用于开发,一种用于生产。基本有两种实现方式,一个配置文件和多个配置文件。一个配置文件时,执行webpack命令时,提供环境变量,配置文件中获取到环境变量,根据不同的值,提供不同的配置。webpack --env production,production就是环境变量, 如果没有设置值,那就true. 此时,配置文件中要exports 出一个函数,函数的第一个参数就环境变量,函数返回配置对象。新建webpack.config.js,webpack默认的配置文件名,webpack打包的时候,自动会找webpack.config.js文件,
module.exports = (env) => {
if (env === 'production') {
return ({
// 生产环境配置英
})
} else {
return ({
// 开发环境配置英
})
}
}
多个配置文件就是为每一个环境提供一个配置文件,执行webapck命令时,用--config指定使用哪一个配置文件。我更倾向于使用多个配置文件,简洁明了。新建webpack.dev.config.js. 配置文件有几个重要的概念,entry, output, module, plugins。
entry:打包的入口文件,就是webpack在进行打包的时候,从哪个文件开始。
output:打包后的文件放到什么地方,以及文件名是什么
module:处理哪些模块,用什么规则处理,规则就是指定loaders。loaders就是告诉webpack怎么处理不认识的文件,把它转化成JS,因为webpack只认识js文件, 只有转化成JS,webpack才能进行打包
plugins:打包过程其它的事情,比如压缩,生成html文件,扩展了webpack的功能
由于有零配置,webpack提供了默认的entry和output, 如果觉得ok,配置文件中可以只写module 和plugins,mode也可以在配置文件中配置,npm run 命令中的 --mode去掉,webpack.dev.config.js如下
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: 'development',
plugins: [
new HtmlWebpackPlugin(),
],
};
如果觉得不ok 的话,可以写entry 和output, 把它覆盖掉,。webpack.dev.config.js如下
const path = require('path'); const htmlWebpackPlugin = require('html-webpack-plugin'); // 引入插件 module.exports = { mode: 'development', entry: path.join(__dirname, 'src/index.js'), output: { path: path.join(__dirname, 'dist'), filename: 'main.js' }, plugins: [ new htmlWebpackPlugin() ] }
output的path要使用绝对路径,因此使用了Node.js内置path模块。plugins是个数组,每一个用到的插件都是数组中的一项。具体到每一个插件呢?插件都会暴露出构造函数,通过new 调用,就可以使用,如果插件还有配置项,就给构造函数传递一个配置对象作为参数。dev命令改成
"dev": "webpack --config webpack.dev.config.js",
npm run dev 打包成功,查看一下,没有问题。
但前端不止JS,还有CSS,图片等。想要把页面更美观一点,写一点CSS,在src下新建style.css
body {
background: cornsilk;
}
并index.js引入,打包,发现wepack 不认识CSS,要配置loader。处理CSS两个基本loader,css-loader和style-loader, npm i css-loader style-loader -D
module.exports = {
mode: 'development',
module: {
rules: [
{ test: /\.css$/, use: ["style-loader", "css-loader"] },
],
},
plugins: [
new HtmlWebpackPlugin(),
],
};
当使用多个loader来处理同一个文件时,要注意loader的执行顺序,它是按照从右到左,从下到上的顺序执行。css-loader 先执行,然后把执行结果交给style-loader,最终style-loader返回js,这样webpack才能打包。css-loader:将css的代码按照commonJS的规范转化成js,将css代码输出到打包后的JS文件中。style-loader是把包含css内容的JS代码,挂载到页面的