創建目錄
項目名稱: vue-init
app
├─css
│ reset.scss
│
├─js
│ │ App.vue
│ │ main.js
│ │
│ ├─home
│ │ index.vue
│ │
│ └─router
│ index.js
│
└─views
index.html
安裝webpack
npm i -D webpack
創建配置文件
webpack.config.js
基礎配置
- entry 入口
- module 模塊
- plugins 插件
- output 輸出
進階配置
- resolve
- devtool
- devServer
- ...
基礎配置
步驟
先寫好基本結構
module.exports = {
enter: {},
module: {},
plugins: [],
output: {}
}
配置入口文件,以main.js作為打包入口文件
enter: {
app: './app/js/main.js'
}
配置module,里面主要配置使用的各種loader
module: {
rules: [
{
test: /\.html$/,
use: [
{
loader: 'html-loader'
}
]
},
{
test: /\.vue$/,
use: [
{
loader: 'vue-loader'
}
]
},
{
test: /\.scss$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
module: true
}
},
{ loader: 'sass-loader' },
]
},
]
},
- test 的值為正冊表達式,配對文件后綴,表示什么文件對應的loader
- sass 需要使用多個loader,解析順序是從右向左
options: { module: true }
開啟css module
稍后再配置plugins,先配置output
//在webpack.config.js頂部引入path
const path = require('path');
output: {
filename: '[name].min.js',
path: path.resolve(_dirname, 'dist')
}
}
- filename表示打包后輸出的文件名
- [name] 對應 enter.app的值
- path 打包輸出的路徑
- path.resolve() webpack的執行環境是node,這里的path是node里的一個對象,用於處理文件路徑和目錄路徑
配置好了 我們開始安裝loaders
npm i -D html-loader vue-loader style-loader css-loader sass-loader
如果有loader安裝不成功請再單個安裝它,或者換用cnpm
基礎配置代碼
到這一步我們的基礎配置已經做好,代碼如下:
module.exports = {
enter: {
app: './app/js/main.js'
},
module: {
rules: [
{
test: /\.html$/,
use: [
{
loader: 'html-loader'
}
]
},
{
test: /\.vue$/,
use: [
{
loader: 'vue-loader'
}
]
},
{
test: /\.scss$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
module: true
}
},
{ loader: 'sass-loader' },
]
},
]
},
plugins: [],
output: {
filename: '[name].min.js',
path: path.resolve(_dirname, 'dist')
}
}
進階配置
devServer
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 9000
}
- contentBase 告訴服務器從哪個目錄中提供內容。
- compress 壓縮
- port 啟動端口號
配置好了 我們開始安裝它
npm i -D webpack-dev-server
測試
添加一些代碼以供測試
home/index.vue
<template>
<div id="home">
<h1>首頁</h1>
<p>123123<p>
</div>
</template>
<script>
export default {}
</script>
<style lang="scss" scoped>
.home {
color: red;
font-size: 80px;
p {
color: blue
}
}
</style>
router/index.js
import Vue from "vue"
import Router from "vue-router"
import Home from "../home/index.vue"
Vue.use(Router);
export default new Router({
routes: [{
path: '/',
name: 'home',
component: Home
}]
})
App.vue
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app'
};
</script>
<style lang="scss" scoped>
</style>
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false;
new Vue({
router,
render: h => h(App)
}).$mount("#app")
我們還需要安裝 vue 和vue router
npm i vue vue-router
運行devServer
還需要安裝兩個依賴
npm i -D html-webpack-plugin clean-webpack-plugin
webpack.config.js頂部加入如下代碼
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
// 注意這里的寫法, 這樣寫 const CleanWebpackPlugin 會報錯
- html-webpack-plugin
官網文檔解釋:HtmlWebpackPlugin簡化了HTML文件的創建,以便為你的webpack包提供服務。這對於在文件名中包含每次會隨着編譯而發生變化哈希的 webpack bundle 尤其有用。 你可以讓插件為你生成一個HTML文件,使用lodash模板提供你自己的模板,或使用你自己的loader。另外你可以在github查看這個項目的詳細配置。
- clean-webpack-plugin 在每次構建前清理 /dist 文件夾,這樣只會生成用到的文件。
配置plugins
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: './views/index.html'
})
],
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
package.json 加入 "start": "webpack-dev-server --open"
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --open"
},
跑完發現一大堆報錯
- You may need an additional loader to handle the result of these loaders. Vue-loader在15.*之后的版本都是 vue-loader的使用都是需要伴生 VueLoaderPlugin的
npm i vue-loader-plugin -S
webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
// ...
plugins: [
new VueLoaderPlugin()
]
}
- Cannot find module 'node-sass'
安裝就完了,最后我們npm start 項目成功運行
px2rem
npm install -D px2rem-loader
module: {
rules: [
{
test: /\.html$/,
use: 'html-loader'
},
{
test: /\.vue$/,
use: 'vue-loader'
},
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'px2rem-loader',
options: {
remUnit: 75,
remPrecision: 6
}
},
'sass-loader'
]
},
]
},
這部分為什么這么配置,參考了Vue官方文檔 -> 單文件組建 -> 針對高級用戶 -> VueLoader
原來的webpack3.x需要在vue-loader 下配置css 和 sass 並配置 px2rem。
css module
// ...
{
test: /\.scss$/,
use: [
'vue-style-loader',
+ {
+ loader: 'css-loader',
+ options: {
+ modules: true,
+ localIdentName: '[local]_[hash:base64:8]'
+ }
+ },
{
loader: 'px2rem-loader',
options: {
remUnit: 75,
remPrecision: 6
}
},
'sass-loader'
]
},
如果你不知道如何使用css module 請參閱Vue官方文檔 -> 單文件組建 -> 針對高級用戶 -> VueLoader -> css module
css提取
npm install -D mini-css-extract-plugin
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: true
}
},
{
loader: 'px2rem-loader',
options: {
remUnit: 75,
remPrecision: 6
}
},
'sass-loader'
]
},
plugins: [
// ...
new MiniCssExtractPlugin({
filename: 'style.css'
})
]
區分生產環境和開發環境
webpack3
我們需要使用webpack的DefinePlugin創建一個在編譯時可以配置的全局常量。在webpack.config.js頭部引入webpack
const webpack = require('webpack');
接下來我們把module.exports的值改為箭頭函數,並傳入一個參數env
module.exports = env => {
if (!env) { env = {} }
return {
// 原來的配置
}
}
我們先來做一個示例,例如我們在開發環境不需要css提取
module.exports = env => {
if (!env) { env = {} }
let plugins = [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: './views/index.html'
}),
new VueLoaderPlugin(),
];
if (env.production) {
plugins.push(
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: 'production'
}
}),
new MiniCssExtractPlugin({
filename: 'style.css'
})
)
}
- process 對象是屬於node的一個全局變量
- 我們只需要根據是否傳入了env.production,然后給plugins數組push生產環境下需要的MiniCssExtractPlugin插件
對應的我們還有修改部分原來的代碼
{
test: /\.scss$/,
use: [
* env.production?MiniCssExtractPlugin.loader:'vue-style-loader',
{
loader: 'css-loader',
options: {
modules: true
}
},
{
loader: 'px2rem-loader',
options: {
remUnit: 75,
remPrecision: 6
}
},
'sass-loader'
]
},
以及原來的plugins配置我們直接將它的值變為我們上面定義的plugins。
package.json中我們需要添加命令
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --open",
"watch": "webpack --watch",
"build" : "webpack --env.production"
},
注意我們給webpack 傳遞了參數,我們就是利用這個參數來區分環境。
npm start
控制台我們可以看到
css樣式以style標簽插入,並沒有被提取,說明MiniCssExtractPlugin插件沒有運行
npm run build
運行打包后的index.html,css樣式以link標簽插入,說明css被提取合並為一個文件,說明生產環境下MiniCssExtractPlugin插件運行了
webpack4
上面是的做法看起來更好理解,webpack4中我們可以直接利用mode來區分開發環境和生產環境。頭部我們不需要引入webpack了, 因為我們不需要依賴 DefinePlugin。
配置中新增:
mode: 'development' //默認是 development
module.exports = (env, argv) => {
if (argv.mode === 'production') {
//...
}
return config;
};
eslint
npm i eslint -D
eslint支持多種格式的配置文件,同時支持把配置直接寫在package.json中,我們直接在寫在package.json中,如何配置呢?
vue項目可以直接使用vue官方推薦的插件
npm i eslint-plugin-vue -D
package.json添加如下:
{
// 其他配置
"eslintConfig": {
"root": true,
"parserOptions": {
"ecmaVersion": 2017
},
"extends": [
"mysticatea",
"mysticatea/modules",
"plugin:vue/recommended"
],
"plugins": [
"node"
],
"env": {
"browser": false
},
"globals": {
"applicationCache": false,
"atob": false,
"btoa": false,
"console": false,
"document": false,
"location": false,
"window": false
},
"rules": {
"node/no-extraneous-import": "error",
"node/no-missing-import": "error",
"node/no-unpublished-import": "error",
"vue/html-indent": [
"error",
4
],
"vue/max-attributes-per-line": "off"
}
},
"eslintIgnore": [
"node_modules",
"webpack.config.js"
]
}