正文前先吐槽下, webpack 对新手入门真的有点不友好,各个版本在配置上都有或多或少的差异,导致在对照各种教程学习的过程中免不了掉进各种坑里,所以写这篇文章旨在简单明了的解释说明 webpack 的各种常用配置,希望能让新人接触 webpack 时少走些弯路。
一、搭建项目
1. 我们先新建一个项目 project 并用 npm 命令初始化项目(一路回车)
npm init
复制代码
2. 安装 webpack 与 webpack-cli ( 4 版本需要cli才能执行命令)
npm install --save-dev webpack webpack-cli
复制代码
3. 新建 src 文件夹,存放我们要打包的源码,默认输入文件是 index.js,所以我们在 src 下新建一个index.js文件
document.write("测试文件打包")
复制代码
4. 执行命令,便能实现最简单的 “ 项目打包 ”
webpack
复制代码
5. 输入命令打包完成后会生成一个 dist 文件夹,里面就存放着我们需要打包的文件,这样一个最简单的 webpack 打包流程到此完工,接下来就要进入正片了。
二、命令部分
1. webpack 默认打包命令
第一部分我们使用过 webpack 命令进行打包,其实这个命令是不完整的,细心的小伙伴会发现执行时控制台会有提示该命令有 production(生产) 与 development (开发)模式,完整命令如下:
// 两个命令有和不同就请大家自己手动试一下,这里就不赘述了
webpack --mode production
webpack --mode development
复制代码
2. webpack 根据配置文件打包命令
实际中我们打包项目根据需要会有各种配置,因此常用的是根据配置文件来进行打包,所以我们在项目根目录下新建一个 webpack.conf.js 文件来保存配置信息
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
}
}
复制代码
稍后会对这个文件进行详细讲解,这里先执行命令看是否能成功进行按需打包
// webpack.conf.js 可根据自己需要命名 打包方法是 --config 配置文件路径
webpack --mode production --config ./webpack.conf.js
复制代码
打包成功会发现在 dist 下现在生成的文件名已经由默认变成了我们指定的 bundle.js
3. 改写 npm 命令
由于 webpack 指令比较长,输入时很不方便,我们有个小技巧可以简化这一步骤,就是对项目的 package.json 文件中的 script 部分进行修改
"scripts": {
"dev": "webpack --mode development --config ./webpack.conf.js",
"build": "webpack --mode production --config ./webpack.conf.js"
},
复制代码
然后执行以下命令就相当于执行了我们所设置对应的完整 webpack 命令
npm run dev
npm run build
复制代码
三、配置部分
这部分会涉及很多内容,包括一些常用插件,我会逐步带大家完善 webpack.conf.js 文件,但基本点到即止,详细配置还需参考官方文档自行配置
1. 关于文件路径
配置文件会有许多关于文件路径的设置,这方面一不小心就会出现问题,这里推荐采以下方法对相对路径进行处理
const path = require('path')
// 此方法会根据传入的相对路径自动转化为绝对路径,确保路径的正确
path.resolve(__dirname, '文件的相对路径')
复制代码
- webpack.conf.js 配置例子
const path = require('path')
module.exports = {
entry: path.resolve(__dirname, './src/index.js'),
output: {
filename: 'main.js',
}
}
复制代码
2. 配置文件结构总览
主要包含以下 4 个部分 entry:配置文件入口 output:配置输出文件名与路径 plugins:配置引入的插件 module: 配置文件转换的规则
const path = require('path')
module.exports = {
// 输入路径配置
entry: path.resolve(__dirname, './src/index.js'),
// 输出文件名和路径配置
output: {
filename: 'main.js',
path: path.resolve(__dirname, './dist')
},
// 引入插件配置
plugins: [],
// 文件类型转换配置
module: {}
}
复制代码
对文件结构有个总体了解后我们接下来就开始逐步完善
3. 完善 js 文件输出路径
通常项目我们有一个专门的 js 文件夹进行存放 js 文件,并且为了区分版本,我们有时会使用 hash 进行区分( hash 值仅当源码文件被修改时才会更新)
- webpack.conf.js 配置例子
const path = require('path')
module.exports = {
// 输入路径配置
entry: path.resolve(__dirname, './src/index.js'),
// 输出文件名和路径配置
output: {
// [name] 可自行配置,参考文档
// [hash:4] 使用 hash 取前 4 位
filename: 'js/[name]-[hash:4].js',
path: path.resolve(__dirname, './dist')
},
// 引入插件配置
plugins: [],
// 文件类型转换配置
module: {}
}
复制代码
4. 使用插件,引入 html 模板
目前为止,我们打包的都只有 js 文件,作为前端项目,怎么可以没有 html 文件呢,为了实现打包自动生成 html 文件,我们开始引入我们的第一个插件
- 安装插件 html-webpack-plugin
npm install --save-dev html-webpack-plugin
复制代码
- 在项目根目录下新建 index.html 文件作为模板,供配置文件引入
- webpack.conf.js 配置例子
const path = require('path')
const htmlWebpackPlugins = require('html-webpack-plugin')
module.exports = {
// 输入路径配置
entry: path.resolve(__dirname, './src/index.js'),
// 输出文件名和路径配置
output: {
filename: 'js/main.js',
path: path.resolve(__dirname, './dist')
},
// 引入插件配置
plugins: [
new htmlWebpackPlugins({
// 输出文件名
filename: 'index.html',
// 所引用模板文件位置
template: 'index.html',
// js 文件插入的位置
inject: 'body'
}),
],
// 文件类型转换配置
module: {}
}
复制代码
现在尝试下打包,基本的 html 和 js 文件就有了,但这远远还不够,我们还需要对 html 与 js 的相关配置进行处理,为了使项目更完整,我们还要新建一些文件。
5. 完善项目目录
- 在 src 目录下新建 components 文件夹,分别新建 html, js, css 文件 ,下面以 scroll 组件为例
scroll.html
"scroll">
scroll
复制代码
scroll.js
// import tpl from './scroll.html'
// import './scroll.css'
function scroll () {
return {
name: 'scroll',
// tpl: tpl
}
}
export default scroll
复制代码
scroll.css
.scroll {
height: 500px;
width: 500px;
background: red;
}
.scroll p {
display: flex;
}
复制代码
- 文件新建完还需在我们的入口文件 index.js 中引入
import Scroll from './components/scroll'
const App = function () {
var dom = document.getElementById('app')
var scroll = new Scroll()
dom.innerHTML = scroll.tpl
document.write(scroll.name)
}
new App()
复制代码
- 最后修改下我们的 index.html 模板,新增 app 模块
"en">
"UTF-8">
"viewport" content="width=device-width, initial-scale=1.0">
"X-UA-Compatible" content="ie=edge">
Document
"app">
复制代码
这时尝试打包,便可把我们新增的 scroll.js 引入进来了,但是这时我们 tpl 也就是 scroll.html 还处于注释状态,想要正确引入,还需添加其他插件
6. 使用插件,配对 .html 类型文件(之后的 .css, .png等其他类型的文件引入方法与此类似)
- 安装插件 html-loader
npm install --save-dev html-loader
复制代码
- 修改我们的 webpack.conf.js ,在 module 中完善我们的文件转换配置
const path = require('path')
const htmlWebpackPlugins = require('html-webpack-plugin')
module.exports = {
entry: path.resolve(__dirname, './src/index.js'),
output: {
filename: 'js/main.js',
path: path.resolve(__dirname, './dist')
},
plugins: [
new htmlWebpackPlugins({
filename: 'index.html',
template: 'index.html',
inject: 'body'
}),
],
// 文件类型转换配置
module: {
rules: [
{
// 正则匹配 html 文件
test: /\.html$/,
use: [
{
// 引入 html 文件加载插件
loader: 'html-loader'
}
]
}
]
}
}
复制代码
- 修改下我们的 scroll.js 文件,将之前的注释取消
import tpl from './scroll.html'
// import './scroll.css'
function scroll () {
return {
name: 'scroll',
tpl: tpl
}
}
export default scroll
复制代码
- OK ~ 尝试打包,现在应该就能正确的把 scroll.thml 的内容也打包进去了,成功之后我们就只剩 .css 类型文件没有打包进去,那么继续我们的配置
7. 使用插件,配对 .css 类型文件
- 安装插件 css-loader 与 style-loader
npm install --save-dev css-loader style-loader
复制代码
- 修改我们的 webpack.conf.js, 添加匹配规则
const path = require('path')
const htmlWebpackPlugins = require('html-webpack-plugin')
module.exports = {
// 输入路径配置
entry: path.resolve(__dirname, './src/index.js'),
// 输出文件名和路径配置
output: {
filename: 'js/main.js',
path: path.resolve(__dirname, './dist')
},
// 引入插件配置
plugins: [
new htmlWebpackPlugins({
filename: 'index.html',
template: 'index.html',
inject: 'body'
}),
],
// 文件类型转换配置
module: {
rules: [
{
// 正则匹配 html 文件
test: /\.html$/,
use: [
{
// 引入 html 文件加载插件
loader: 'html-loader'
}
]
},
{
// 正则匹配 css 文件
test: /\.css$/,
use: [
{
// 引入 style 文件加载插件
loader: 'style-loader'
},
{
// 引入 css 文件加载插件
loader: 'css-loader'
}
]
},
]
}
}
复制代码
- 修改下我们的 scroll.js 文件,将之前 css 的注释也取消
import tpl from './scroll.html'
import './scroll.css'
function scroll () {
return {
name: 'scroll',
tpl: tpl
}
}
export default scroll
复制代码
- 进行打包,成功后自己看看效果,这样一个简单 webpack 打包流程就已经走完了
至此,相信你对 webpack 的基本工作流程有了一定的了解,不过这只是刚刚开始,上面的例子离我们实际工作中的应用还有一段距离,例如 js 没有实现 ES6 到 ES5 的转换,css 样式不是以一个文件的形式插入,遇到引入图片文件时上面的配置会出现错误,还有许多我们常用的框架文件如 vue 等文件类型要打包时都是需要重新配置的,本文就不再对配置进行深究,只是简单多介绍一些常用插件供大家学习了解
8. 插件介绍
- babel-loader , babel-preset-latest , babel-core 用于ES6 到 ES5 的转换
- autoprefixer , postcss-loader 用于 css 根据配置的浏览器版本进行自动添加前缀
- less, less-loader 用于试别 less 类型样式文件(sass等同理,引入相应插件进行配置)
- url-loader 用于加载图片类型文件
- image-webpack-loader 用于优化图片文件加载
- mini-css-extract-plugin 用于分离压缩 css 文件