为了让浏览器能够正确的解析, 我们需要使用 webpack 将我们的源代码进行打包
在根目录下创建 webpack 配置文件 webpack.config.js, 编写最基本的配置
示例
// 使用node的path模块
const path = require('path')
module.exports = {
// 打包的入口
entry: './src/main.js',
// 打包的出口
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
}
演示
在 packpage.json 中, 创建一个执行脚本
这样就可以通过npm run build
来执行 webpack 打包了
在命令行中执行npm run build
会发现提示这个错误
原因是: webpack 只能打包 js 文件. 对于后缀名为 vue 的文件不能打包. 如何解决呢?
通过 vue-loader 来打包 vue 文件
==============================================
找到 vue-loader 官网(opens new window)
对于最新的 vue-loader@15 版本, 按照官网的指导, 做如下配置
执行命令, 安装 vue-loader
npm install -D vue-loader vue-template-compiler
安装完成后, 发现 vue-loader 依赖 css-loader, 因此我们也要手动安装一下 css-loader
执行npm install -D css-loader
从 vue-load@15 版本开始, vue-loader 需要在 webpack 中添加一个插件
示例
// 使用node的path模块
const path = require('path')
// 引入vue-loader插件
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
// 打包的入口
entry: './src/main.js',
// 打包的出口
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
// 打包规则
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
},
],
},
plugins: [
// 请确保引入这个插件!
new VueLoaderPlugin(),
],
}
演示
重新打包, 在 dist 目录下就会生成 bundle.js
解决警告小问题
我们发现在 webpack 打包时会出现这个警告
解决
找到 webpack.config.js 在配置中添加 mode
在 index.html 中引入 bundle.js 测试, 发现报错
原因
Vue 会打包生成三个文件:
而默认导出的是 vue.common.js, 如何解决呢?
解决
在 webpack 中, 添加别名的配置
resolve: {
alias: {
'vue': 'vue/dist/vue.js'
}
},
演示
重新打包, 测试
通过上面的练习, 我们知道
=====================================
一般来说, 一个前端项目除了 js 文件外, 还有一些常用的文件, 如
对于这些文件, webpack 都不会打包, 需要我们安装对应的 loader 帮助 webpack 打包
file-loader: 将文件复制到对应的路径, 并返回文件名
file-loader官方文档(opens new window)
#i 安装 file-loader
执行命令, 安装 file-loader
npm install -D file-loader
演示
#ii 配置
修改 webpack 配置, 添加一条规则
module: {
rules: [
{
test: /\.(jpg|jpeg|png|svg)$/,
loader: 'file-loader',
},
]
}
演示
#iii 测试
在 src 目录下创建 assets 目录, 存放静态资源文件(如: images/styles/fonts 等)
在 images 下放一张图片
在 App.vue 中导入图片, 重新打包, 会在 dist 目录下生成我们需要的图片
原理: 当遇到 jpg 结尾的文件时, 使用 file-loader 将文件 copy 到 dist 目录下. 文件名是图片的 hash 值
如果希望保留原有的文件名, 可以使用占位符(placeholder)配置
示例
{
test: /\.(jpg|jpeg|png|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]'
}
}
[name]
: 占位符, 表示使用原文件名[ext]
: 占位符, 表示使用原文件扩展名演示
url-loader: 功能类似于 file-loader (opens new window),但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL。
好处是: 直接将小图片打包以 base64 打包在 js 中, 减少 Http 请求的次数, 提高访问效率
#i 安装 url-loader
执行命令, 安装 url-loader
npm install -D url-loader
提示
由于 url-loader 依赖 file-loader, 因此安装 url-loader 需要先安装 file-loader, 一般来说执行如下命令更适合
npm install -D file-loader url-loader
同时安装 file-loader 和 url-loader
演示
#ii 配置
修改 webpack 配置, 添加一条规则
module: {
rules: [
{
test: /\.(jpg|jpeg|png|svg)$/,
loader: 'url-loader',
options: {
name: '[name].[ext]',
limit: 2048,
},
},
]
}
#iii 测试
复制两张小的 svg 图片到 assets 目录下. 并在 App.vue 中导入
运行打包命令npm run build
, 在新生成的 bundle.js 中, 可以看到
css 文件是前端项目必不可少的文件, webpack 通过 css-loader 和 style-loader 来打包 css 文件
官方文档(opens new window)
#i 安装 css-loader
在安装 vue-loader 时, 我们已经安装了 css-loader. 可以通过查看package.json
确认
#ii 安装 style-loader
在命令行中执行如下命令
npm install -D style-loader
演示
示例
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}]
},
注意
这里的书写顺序是有讲究的, 按照从右到左, 从下到上的顺序依次执行
在 styles 目录下创建 test.css 文件, 编写如下内容
示例
* {
margin: 0;
padding: 0;
}
body {
background-color: red;
}
演示
在 App.vue 中导入 test.css
执行命令npm run build
重新打包, 测试, 发现生效
css-loader: 解决文件之间的依赖关系, 把所有的 css 文件打包成一个文件
style-loader: 将 css-loader 打包完成后生成的文件挂载到页面的 head 标签的 style 中
示例
比如, 在实际项目中一般会把初始化样式独立出来, 再通过 import 引入
css-loader 为分析 css 文件之间的引用关系, 最终形成一个整体文件
再通过 style-loader 将 css-loader 的内容挂载到页面的 head 的 style 标签中
目前, stylus 做为 node 项目普通使用的 css 预处理器被广泛的应用于 vue 项目中. 大家会发现大部分的 vue 项目中都会使用 stylus 来编写 css.
;
, :
这里我对 Supermacy 的配置如下,
不使用{}, 不使用结尾的;
, 但是保留:
配置之后, stylus 的样子如下:
#i 安装 stylus-loader
执行命令
npm install -D stylus stylus-loader
#ii 配置
示例
module: {
rules: [{
test: /\.styl(us)?$/,
use: ['style-loader', 'css-loader', 'stylus-loader']
}]
},
#iii 测试
在 styles 下编写 global.styl 文件, 编写如下内容, 这个也是响应式背景全屏的方案
示例
body
// 背景图片
background-image: url('..//http://image.brojie.cn/bg.jpg')
// 背景图片位置固定
background-attachment: fixed
// 背景不要重复
background-repeat: no-repeat
// 背景位置居中
background-position: center center
// 背景覆盖整个viewport
background-size: cover
// 当背景没有加载时的颜色
background-color: #fff
演示
在 App.vue 中引入 global.styl
示例
import './assets/styles/global.styl'
演示
由于在开发环境, 打包后的文件路径都是相对于 dist 目录, 因此我们还需要暂时把 index.html 移动到 dist 下, 并做如下修改
打包以后测试如下
在 vue-loader 的官方文档中找到关于 stylus 的配置(opens new window)
#i 安装
在前面, 我们已经安装了 stylus 和 stylus-loader, 这里就不用再安装了
#ii 配置
修改 webpack.config.js
示例
module: {
rules: [{
test: /\.styl(us)?$/,
use: ['vue-style-loader', 'css-loader', 'stylus-loader']
}]
},
#iii 测试
我们在 App.vue 中修改一下
打包测试
===============================================
什么是插件
在某个时间点, 自动执行的处理程序(类似于 vue 的生命周期函数)
查看该插件的官方文档(opens new window)
执行命令
npm install -D html-webpack-plugin
修改 webpack.config.js
在 dist 目录下, 生成了 index.html, 并且自动引入了打包后的 js 文件
这时, 我们直接访问发现只有背景, 没有 App 的内容, 并且报了一个 vue 的错误
我们发现自动生成的 html 中没有 id 为 app 的 div 元素, 如何解决这个问题?
其实, 我们是可以指定生成 html 时, 以哪个文件为模板的
修改 webpack 配置
示例
plugins: [
new HtmlWebpackPlugin({
template: './index.html'
})
],
演示
html-webpack-plugin 的作用:
在打包结束时, 在 dist 目录下自动生成 index.html 文件, 并把打包好的 js 文件引入到 html 中
执行命令
npm install -D clean-webpack-plugin
1
webpack 的相关配置
第 10 行: 加{}是 ES6 中的解构的语法, 作用是提取出 CleanWebpackPlugin 的构造函数
autoprefixer 插件是 postcss-loader 提供的一个插件, 如果要使用这个插件, 我们得先安装 postcss-loader
npm install -D postcss-loader autoprefixer
webpack 配置
新建 postcss.config.js 配置文件
示例
module.exports = {
plugins: [require('autoprefixer')],
}
演示
测试发现, 会自动添加厂商前缀
==============================
webpack-dev-server
为你提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)。
查看该部分的相关文档(opens new window)
#i 安装
执行命令
npm install -D webpack-dev-server
#ii 基本配置
示例
webpack 配置
// devServer配置
devServer: {
// 指定服务器根目录
contentBase: './dist',
// 自动打开浏览器
open: true
},
在 package.json 中添加一个脚本
示例
"scripts": {
"start": "webpack-dev-server"
},
在命令行中执行npm run start
启动 devServer
测试发现, 只要代码修改后, webpack 会自动重新打包, 页面会重新刷新加载. 这样就不需要每次执行打包命令了
查看该部分的相关文档(opens new window)
查看该部分的相关文档(opens new window)
#i 配置
示例
devServer: {
// 指定服务器根目录
contentBase: './dist',
// 自动打开浏览器
open: true,
// 启用热模块替换
hot: true
},
#ii 插件
编写业务代码 App.vue
示例
TodoList
- {{ item }}
修改颜色, 发现之前添加的内容依然存在
SourceMap: (源代码映射) 建立打包后的文件和源代码所在行的映射,
主要作用: 在开发时快速定位到出错的源代码行
查看该部分的相关文档(opens new window)
以及相关文档(opens new window)
开发环境(development) 和 生产环境(production) 的构建目标差异很大。
因此, 配置会有所不同, 官方推荐使用两个不同的配置文件
示例
webpack.dev.js
// 使用node的path模块
const path = require('path')
// 引入vue-loader插件
const VueLoaderPlugin = require('vue-loader/lib/plugin')
// 导入html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 导入clean-webpack-plugin
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// 导入webpack
const webpack = require('webpack')
module.exports = {
// 模式
mode: 'development',
devtool: 'cheap-module-eval-source-map',
// 打包的入口
entry: './src/main.js',
// devServer配置
devServer: {
// 指定服务器根目录
contentBase: './dist',
// 自动打开浏览器
open: true,
// 启用热模块替换
hot: true,
},
// 插件
plugins: [
// 请确保引入这个插件!
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
template: './index.html',
}),
new CleanWebpackPlugin(),
new webpack.HotModuleReplacementPlugin(),
],
// 打包的出口
output: {
filename: 'app.js',
path: path.resolve(__dirname, 'dist'),
},
// 打包规则
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
test: /\.(jpg|jpeg|png|svg)$/,
loader: 'url-loader',
options: {
name: '[name].[ext]',
limit: 2048,
},
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.styl(us)?$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'],
},
],
},
resolve: {
alias: {
vue: 'vue/dist/vue.js',
},
},
}
webpack.prod.js
// 使用node的path模块
const path = require('path')
// 引入vue-loader插件
const VueLoaderPlugin = require('vue-loader/lib/plugin')
// 导入html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 导入clean-webpack-plugin
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
// 模式
mode: 'production',
// 打包的入口
entry: './src/main.js',
// 插件
plugins: [
// 请确保引入这个插件!
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
template: './index.html',
}),
new CleanWebpackPlugin(),
],
// 打包的出口
output: {
filename: 'app.js',
path: path.resolve(__dirname, 'dist'),
},
// 打包规则
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
test: /\.(jpg|jpeg|png|svg)$/,
loader: 'url-loader',
options: {
name: '[name].[ext]',
limit: 2048,
},
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.styl(us)?$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'],
},
],
},
resolve: {
alias: {
vue: 'vue/dist/vue.js',
},
},
}
修改 package.json
"scripts": {
"dev": "webpack-dev-server --config ./webpack.dev.js",
"build": "webpack --config ./webpack.prod.js"
},
使用 webpack-merge 工具
执行命令
npm install -D webpack-merge
创建 3 个文件
示例
webpack.base.js
// 使用node的path模块
const path = require('path')
// 引入vue-loader插件
const VueLoaderPlugin = require('vue-loader/lib/plugin')
// 导入html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 导入clean-webpack-plugin
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
// 打包的入口
entry: './src/main.js',
// 插件
plugins: [
// 请确保引入这个插件!
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
template: './index.html',
}),
new CleanWebpackPlugin(),
],
// 打包的出口
output: {
filename: 'app.js',
path: path.resolve(__dirname, '..', '/dist'),
},
// 打包规则
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
test: /\.(jpg|jpeg|png|svg)$/,
loader: 'url-loader',
options: {
name: '[name].[ext]',
limit: 2048,
},
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.styl(us)?$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'],
},
],
},
resolve: {
alias: {
vue: 'vue/dist/vue.js',
},
},
}
webpack.dev.js
// 导入webpack
const webpack = require('webpack')
const merge = require('webpack-merge')
const baseConfig = require('./webpack.base.js')
const devConfig = {
// 模式
mode: 'development',
devtool: 'cheap-module-eval-source-map',
devServer: {
// 指定服务器根目录
contentBase: './dist',
// 自动打开浏览器
open: true,
// 启用热模块替换
hot: true,
},
// 插件
plugins: [new webpack.HotModuleReplacementPlugin()],
}
module.exports = merge(baseConfig, devConfig)
webpack.prod.js
const merge = require('webpack-merge')
const baseConfig = require('./webpack.base.js')
const prodConfig = {
// 模式
mode: 'production',
}
module.exports = merge(baseConfig, prodConfig)
示例
"scripts": {
"dev": "webpack-dev-server --config ./build/webpack.dev.js",
"build": "webpack --config ./build/webpack.prod.js"
},
视频:使用webpack+vue从零开始打造前端项目(2020最新版)_哔哩哔哩_bilibili