前言
webpack
是一个配置化的构建工具,只学习API、看文章很难去理解每一个配置该怎样使用。书上得来终觉浅,若知此事要躬行,撸上一个Demo
去理解webpack
的强大吧。
Demo
是一个要模仿vue-cli
构建出来的项目,会实现以下功能:
- 类似的基本目录结构
- 实现基本的构建和自动刷新开发模式
- 支持
Vue
及其单文件组件格式 - 支持
Sass
- 支持最新语法
- 支持图片
话不多说,GO!🚀
搭建
1. 基本搭建
a. 初始化
# 新建目录
mkdir my-vue
# 进入目录
cd my-vue
# 初始化(-y 跳过交互直接生成 *package.json*)
npm init -y
b. 安装webpack并构建
项目目录下:
npm install webpack webpack-cli --save-dev
- webpack 4+ 版本一定要另外单独安装
webpack-cli
新建src
文件夹,并在文件夹中新建main.js
,并写入:
console.log('hello world!');
新建webpack.config.js
,并写入:
var path = require('path');
var config = {
entry: './src/main.js', // 定义入口文件
output: {
path: path.resolve(__dirname + '/dist'), // 打包生成文件地址
filename: '[name].build.js', // 生成文件名成名
},
};
module.exports = config;
在package.json
里面的scripts
加上一个构建脚本,如下:
...
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode=production"
},
...
执行npm脚本:
npm run build
结果项目目录中多了dist/main.build.js
,证明成功了。
c. 使用html-webpack-plugin
js程序有了,但存在一个问题,我们如何在浏览器中测试应用程序呢?我们创建一个index.html
就能解决,这里我们使用html-webpack-plugin
插件来实现这个目标。
首先定义一些静态资源,新建public
文件夹并在其中新建index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>hello-world</title>
</head>
<body>
<noscript>
<strong>We're sorry but hello-world doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
在public
下放入文件标题图标favicon.ico
,图标样子怎样随意发挥
接下来,安装html-webpack-plugin
:
npm install html-webpack-plugin --save-dev
然后在webpack.config.js
中配置插件:
...
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入html-webpack-plugin
var config = {
...
plugins: [
// 使用html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html', // 生成的文件夹名
template: 'public/index.html', // 模板html
favicon: 'public/favicon.ico', // 标题图标
}),
],
};
module.exports = config;
最后执行npm run build
构建,dist
文件下有生成三个文件,index.html
,favicon.ico
,index.html
,在浏览器打开index.html
,你可以看到这个画面(如下),证明这一步成功了。

打开dist/index.html
,可以看到在原有的public/index.html
加入了两行代码,插件都帮我们引好了js和图标
<!DOCTYPE html>
<html lang="en">
<head>
...
<link rel="shortcut icon" href="/favicon.ico"></head>
<body>
...
<script type="text/javascript" src="/main.build.js"></script></body>
</html>
d. webpack-dev-server(更自动化的开发模式)
构建没问题了,但是如果开发每次测试都要手动构建和刷新是种多难受的体验啊,所以难道我们不能自动化一点吗?答案是可以的。
安装webpack-dev-server
:
npm install webpack-dev-server --save-dev
配置webpack
:
...
var config = {
...
devServer: {
contentBase: path.join(__dirname, "public"),
compress: true, // 是否压缩
port: 9000, // 启动服务端口
hot: true, // 是否自动刷新
open: true, // 是否启动服务后,自动打开浏览器
},
};
module.exports = config;
增加npm脚本:
"scripts": {
...
"serve": "webpack-dev-server"
},
运行npm run serve
,结果是自动打开浏览器并出现之前一样大的浏览器页面,并且你修改src/main.js
的内容,浏览器会实时自动刷新。
2. 支持Vue单文件组件
安装Vue
:
npm install vue --save
因为webpack是只能解析.js
的文件,为了可以解析.vue
文件,我们需要额外安装相关的loader
和plugin
。
安装vue-loader
及其相关编译器:
npm install vue-loader vue-template-compiler --save-dev
安装css-loader
,使webpack能够解析.css
文件:
cnpm install css-loader --save-dev
为了使用上css-loader
和vue-loader
,还需在webpack.config.js
配置:
...
const VueLoaderPlugin = require('vue-loader/lib/plugin');
var config = {
...
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
// 它会应用到普通的 `.css` 文件
// 以及 `.vue` 文件中的 `<style>` 块
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader',
],
},
]
},
plugins: [
...
// 使用vue-loader一定要引入该插件
new VueLoaderPlugin()
]
...
};
module.exports = config;
在src
文件夹中,新建App.vue
:
<template>
<div class="example">{{ msg }}</div>
</template>
<script>
export default {
data () {
return {
msg: 'Hello world!'
}
}
}
</script>
<style>
.example {
color: red;
}
</style>
修改main.js
:
import Vue from 'vue';
import App from './App.vue';
new Vue({
el: '#app',
render: h => h(App),
});
重新执行npm run serve
,就可以看到页面显示Hello world!
。
5. 支持Sass和Babel
我们希望使用Sass语法写css,用最新语法来写JS。
安装Sass:
npm install sass-loader node-sass --save-dev
安装Babel:
npm install babel-core babel-loader --save-dev
webpack.config.js
配置:
...
var config = {
...
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: file => (
/node_modules/.test(file) &&
!/\.vue\.js/.test(file)
)
},
// 它会应用到普通的 `.css` 文件
// 以及 `.vue` 文件中的 `<style>` 块
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader',
],
},
// 普通的 `.scss` 文件和 `*.vue` 文件中的
// `<style lang="scss">` 块都应用它
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
]
}
]
},
...
};
module.exports = config;
src/App.vue
加上:
...
<style lang="scss">
.example {
font-size: 50px;
}
</style>
结果,用Scss写的样式应用到页面上。
4. 支持图片
页面上使用图片是很普遍的需求,我们加上解释图片的配置,主要涉及两个loader,分别是url-loader
和 file-loader
。url-loader
将您的图像转为 base64 形式的字符串,从而减少 HTTP 请求。
url-loader
带有一个 limit 选项,当达到绝对限制后将图像交给 file loader
处理。
安装file-loader
和url-loader
:
npm install file-loader url-loader -save-dev
webpack.config.js
配置:
module: {
rules: [
...
{
test: /\.(jpg|png)$/,
use: {
loader: "url-loader",
options: {
limit: 25000,
},
},
},
]
}
在src
文件夹中创建assets
文件夹,并且在其中添加图标logo.jpg。
src/App.vue
加上加载图片的代码:
<template>
<div class="example">
{{ msg }}
<img :src="url" alt="">
</div>
</template>
<script>
export default {
data () {
return {
msg: 'Hello world!',
url: require('./assets/logo.png'),
}
}
}
</script>
...
最后执行npm run serve
,页面显示如下图,大功告成:

最后
这样一个基本的Vue项目就搭建好了。如果当中有什么错误或者不足的地方,欢迎评论指出。如果这个练手小项目可以帮到你,可以给我点个赞或者加个star。
项目地址: