教你用webpack搭一個vue腳手架[超詳細講解和註釋!]
阿新 • • 發佈:2018-11-14
filename 結構 merge 擴展名 1.4 ats building package with
1.適用人群
1.對webpack知識有一定了解但不熟悉的同學.
2.女同學!!!(233333....)
2.目的
在自己對webpack有進一步了解的同時,也希望能幫到一些剛接觸webpack的同學.
腳手架已放上github,不想聽我啰嗦的同學可以直接去download或clone下來看哦.
腳手架裏都有詳細註釋!
https://github.com/webfansplz...
覺得有幫助到你的同學給個star哈,也算是對我的一種支持!
3.腳手架結構
├── build 構建服務和webpack配置 |—— build.js webpack打包服務 |—— webpack.base.conf.js webpack基本通用配置 |—— webpack.dev.conf.js webpack開發環境配置 |—— webpack.prod.conf.js webpack生產環境配置 ├── config 構建項目不同環境的配置 ├── public 項目打包文件存放目錄 ├── index.html 項目入口文件 ├── package.json 項目配置文件 ├── static 靜態資源 ├── .babelrc babel配置文件 ├── .gitignore git忽略文件 ├── postcss.config.js postcss配置文件 ├── src 項目目錄 |—— page 頁面組件目錄 |—— router vue路由配置 |—— store vuex配置 |—— App.vue vue實例入口 |—— main.js 項目構建入口
4.配置npm scripts
4.1 生成package.json文件,配置npm scripts.
4.1.1 使用 npm init 命令,生成一個package.json文件!
npm init
4.1.2 全局安裝webpack和webpack-dev-server
npm install webpack webpack-dev-server -g
4.1.3 在項目目錄下安裝webpack和webpack-dev-server
npm install webpack webpack-dev-server -D
4.1.4 進入package.json配置npm scripts命令
"scripts": { "dev": "webpack-dev-server --config build/webpack.dev.conf.js", "start": "npm run dev", "build": "node build/build.js" } 通過配置以上命令: 我們可以通過npm start/npm run dev在本地進行開發, scripts.dev命令解讀: 通過webpack-dev-server命令 啟動build文件夾下webpack.dev.conf.js。 也可以通過npm run build 打包項目文件進行線上部署. scripts.build命令解讀: 通過node命令構建build文件夾下的build.js。 命令的配置可以根據自己腳手架的配置文件位置和名稱不同修改哦!
5.構建腳手架目錄
同學們可以通過自己的習慣和喜愛搭建自己的腳手架目錄,下面講解以上面腳手架結構為準!
6.構建config/config.js
6.1 該文件主要用來配置構建開發環境和生產環境差異化的參數.
6.2
const _path = require("path");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
//vue-loader基本配置
const baseVueLoaderConf = {
//引入postcss插件
postcss: {
config: {
path: _path.resolve("../")
}
},
//轉為require調用,讓webpack處理目標資源!
transformToRequire: {
video: "src",
source: "src",
img: "src",
image: "xlink:href"
}
};
//vue-loader 開發環境配置
const devVueLoaderConf = Object.assign({}, baseVueLoaderConf, {
//loaders
loaders: {
css: ["vue-style-loader", "css-loader"],
less: ["vue-style-loader", "css-loader", "postcss-loader", "less-loader"]
},
cssSourceMap: true
});
//vue-loader 生產環境配置
const buildVueLoaderConf = Object.assign({}, baseVueLoaderConf, {
//loaders
loaders: ExtractTextPlugin.extract({
use: ["css-loader", "postcss-loader", "less-loader"],
fallback: "vue-style-loader"
}),
cssSourceMap: false
});
//開發/生產環境 配置參數!
module.exports = {
dev: {
publicPath: "/",
devtoolType: "cheap-module-eval-source-map",
vueloaderConf: devVueLoaderConf,
host: "localhost",
port: "1234",
proxyTable: {}
},
build: {
publicPath: "/",
devtoolType: "source-map",
vueloaderConf: buildVueLoaderConf,
staticPath: "static"
}
};
7.構建build/webpack.base.conf.js
7.1 此文件主要是webpack開發環境和生成環境的通用配置.
7.2
"use strict";
//引入node path路徑模塊
const path = require("path");
//引入webpack生產環境配置參數
const prodConfig = require("../config").build;
//拼接路徑
function resolve(track) {
return path.join(__dirname, "..", track);
}
//資源路徑
function assetsPath(_path) {
return path.join(prodConfig.staticPath, _path);
}
//webpack 基本設置
module.exports = {
//項目入口文件->webpack從此處開始構建!
entry: path.resolve(__dirname, "../src/main.js"),
//配置模塊如何被解析
resolve: {
//自動解析文件擴展名(補全文件後綴)(從左->右)
// import hello from './hello' (!hello.js? -> !hello.vue? -> !hello.json)
extensions: [".js", ".vue", ".json"],
//配置別名映射
alias: {
// import Vue from 'vue/dist/vue.esm.js'可以寫成 import Vue from 'vue'
// 鍵後加上$,表示精準匹配!
vue$: "vue/dist/vue.esm.js",
"@": resolve("src"),
utils: resolve("src/utils"),
components: resolve("src/components"),
public: resolve("public")
}
},
module: {
//處理模塊的規則(可在此處使用不同的loader來處理模塊!)
rules: [
//使用babel-loader來處理src下面的所有js文件,具體babel配置在.babelrc,主要是用來轉義es6
{
test: /\.js$/,
use: {
loader: "babel-loader"
},
include: resolve("src")
},
//使用url-loader(file-loader的一個再封裝)對引入的圖片進行編碼,此處可將小於8192字節(8kb)的圖片轉為DataURL(base64),
//大於limit字節的會調用file-loader進行處理!
//圖片一般發布後都是長緩存,故此處文件名加入hash做版本區分!
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: "url-loader",
options: {
limit: 8192,
name: assetsPath("img/[name].[hash:8].[ext]")
}
}
]
}
};
8.構建 build/webpack.dev.conf.js
8.1 該文件主要用於構建開發環境
8.2
"use strict";
//引入node path路徑模塊
const path = require("path");
//引入webpack
const webpack = require("webpack");
//引入webpack開發環境配置參數
const devConfig = require("../config").dev;
//引入webpack基本配置
const baseConf = require("./webpack.base.conf");
//一個webpack配置合並模塊,可簡單的理解為與Object.assign()功能類似!
const merge = require("webpack-merge");
//一個創建html入口文件的webpack插件!
const HtmlWebpackPlugin = require("html-webpack-plugin");
//一個編譯提示的webpack插件!
const FriendlyErrorsPlugin = require("friendly-errors-webpack-plugin");
//發送系統通知的一個node模塊!
const notifier = require("node-notifier");
//將webpack基本配置與開發環境配置合並!
const devConf = merge(baseConf, {
//項目出口,webpack-dev-server 生成的包並沒有寫入硬盤,而是放在內存中!
output: {
//文件名
filename: "[name].js",
//html引用資源路徑,在dev-server中,引用的是內存中文件!
publicPath: devConfig.publicPath
},
//生成sourceMaps(方便調試)
devtool: devConfig.devtoolType,
//
//啟動一個express服務器,使我們可以在本地進行開發!!!
devServer: {
//HMR控制臺log等級
clientLogLevel: "warning",
// 熱加載
hot: true,
//自動刷新
inline: true,
//自動打開瀏覽器
open: true,
//在開發單頁應用時非常有用,它依賴於HTML5 history API,如果設置為true,所有的跳轉將指向index.html
historyApiFallback: true,
//主機名
host: devConfig.host,
//端口號
port: devConfig.port,
//配置反向代理解決跨域
proxy: devConfig.proxyTable,
//為你的代碼進行壓縮。加快開發流程和優化的作用
compress: true,
// 在瀏覽器上全屏顯示編譯的errors或warnings。
overlay: {
errors: true,
warnings: false
},
// 終端輸出的只有初始啟動信息。 webpack 的警告和錯誤是不輸出到終端的
quiet: true
},
module: {
//處理模塊的規則(可在此處使用不同的loader來處理模塊!)
rules: [
//使用vue-loader處理以vue結尾的文件!
{
test: /\.vue$/,
loader: "vue-loader",
options: devConfig.vueloaderConf
},
//使用vue-style-loader!css-loader!postcss-loader處理以css結尾的文件!
{
test: /\.css$/,
use: [
"vue-style-loader",
{
loader: "css-loader",
options: {
sourceMap: true
}
},
{
loader: "postcss-loader",
options: {
sourceMap: true
}
}
]
},
//使用vue-style-loader!css-loader!postcss-loader處理以less結尾的文件!
{
test: /\.less$/,
use: [
"vue-style-loader",
{
loader: "css-loader",
options: {
sourceMap: true
}
},
{
loader: "less-loader",
options: {
sourceMap: true
}
},
{
loader: "postcss-loader",
options: {
sourceMap: true
}
}
]
}
]
},
plugins: [
//開啟HMR(熱替換功能,替換更新部分,不重載頁面!)
new webpack.HotModuleReplacementPlugin(),
//顯示模塊相對路徑
new webpack.NamedModulesPlugin(),
//編譯出錯時,該插件可跳過輸出,確保輸出資源不會包含錯誤!
// new webpack.NoEmitOnErrorsPlugin(),
//配置html入口信息
new HtmlWebpackPlugin({
title: "hello,xc-cli!",
filename: "index.html",
template: "index.html",
//js資源插入位置,true表示插入到body元素底部
inject: true
}),
//編譯提示插件
new FriendlyErrorsPlugin({
//編譯成功提示!
compilationSuccessInfo: {
messages: [
`Your application is running here: http://${devConfig.host}:${devConfig.port}`
]
},
//編譯出錯!
onErrors: function(severity, errors) {
if (severity !== "error") {
return;
}
const error = errors[0];
const filename = error.file.split("!").pop();
//編譯出錯時,右下角彈出錯誤提示!
notifier.notify({
title: "xc-cli",
message: severity + ": " + error.name,
subtitle: filename || "",
icon: path.join(__dirname, "xc-cli.png")
});
}
})
]
});
module.exports = devConf;
8.3 通過創建以上文件,並下載相應的依賴和創建項目入口,我們就可以通過npm run dev在本地開發vue項目啦!!!
9.創建 build/webpack.prod.conf.js
9.1 此文件主要用於構建生產環境的配置.
9.2
"use strict";
//引入node path路徑模塊
const path = require("path");
//引入webpack
const webpack = require("webpack");
//一個webpack配置合並模塊,可簡單的理解為與Object.assign()功能類似!
const merge = require("webpack-merge");
//引入webpack生產環境配置參數
const prodConfig = require("../config").build;
//引入webpack基本配置
const baseConf = require("./webpack.base.conf");
//一個創建html入口文件的webpack插件!
const HtmlWebpackPlugin = require("html-webpack-plugin");
//一個抽離出css的webpack插件!
const ExtractTextPlugin = require("extract-text-webpack-plugin");
//一個壓縮css的webpack插件!
const OptimizeCSSPlugin = require("optimize-css-assets-webpack-plugin");
//一個拷貝文件的webpack插件!
const CopyWebpackPlugin = require("copy-webpack-plugin");
//資源路徑
function assetsPath(_path) {
return path.join(prodConfig.staticPath, _path);
}
//將webpack基本配置與生產環境配置合並!
const prodConf = merge(baseConf, {
//項目出口配置
output: {
//Build後所有文件存放的位置
path: path.resolve(__dirname, "../public"),
//html引用資源路徑,可在此配置cdn引用地址!
publicPath: prodConfig.publicPath,
//文件名
filename: assetsPath("js/[name].[chunkhash].js"),
//用於打包require.ensure(代碼分割)方法中引入的模塊
chunkFilename: assetsPath("js/[name].[chunkhash].js")
},
//生成sourceMaps(方便調試)
devtool: prodConfig.devtoolType,
module: {
//處理模塊的規則(可在此處使用不同的loader來處理模塊!)
rules: [
//使用vue-loader處理以vue結尾的文件!
{
test: /\.vue$/,
loader: "vue-loader",
options: prodConfig.vueloaderConf
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: ["css-loader", "postcss-loader"],
fallback: "vue-style-loader"
})
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
use: ["css-loader", "less-loader", "postcss-loader"],
fallback: "vue-style-loader"
})
}
]
},
plugins: [
//每個chunk頭部添加hey,xc-cli!
new webpack.BannerPlugin("hey,xc-cli"),
//壓縮js
new webpack.optimize.UglifyJsPlugin({
parallel: true,
compress: {
warnings: false
}
}),
//分離入口引用的css,不內嵌到js bundle中!
new ExtractTextPlugin({
filename: assetsPath("css/[name].[contenthash].css"),
allChunks: false
}),
//壓縮css
new OptimizeCSSPlugin(),
//根據模塊相對路徑生成四位數hash值作為模塊id
new webpack.HashedModuleIdsPlugin(),
//作用域提升,提升代碼在瀏覽器執行速度
new webpack.optimize.ModuleConcatenationPlugin(),
//抽離公共模塊,合成一個chunk,在最開始加載一次,便緩存使用,用於提升速度!
// 1. 第三方庫chunk
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
minChunks: function(module) {
//在node_modules的js文件!
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(path.join(__dirname, "../node_modules")) === 0
);
}
}),
// 2. 緩存chunk
new webpack.optimize.CommonsChunkPlugin({
name: "manifest",
minChunks: Infinity
}),
// 3.異步 公共chunk
new webpack.optimize.CommonsChunkPlugin({
name: "app",
children: true,
// (選擇所有被選 chunks 的子 chunks)
async: true,
// (創建一個異步 公共chunk)
minChunks: 3
// (在提取之前需要至少三個子 chunk 共享這個模塊)
}),
//將整個文件復制到構建輸出指定目錄下
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, "../static"),
to: prodConfig.staticPath,
ignore: [".*"]
}
]),
//生成html
new HtmlWebpackPlugin({
filename: path.resolve(__dirname, "../public/index.html"),
template: "index.html",
favicon: path.resolve(__dirname, "../favicon.ico"),
//js資源插入位置,true表示插入到body元素底部
inject: true,
//壓縮配置
minify: {
//刪除Html註釋
removeComments: true,
//去除空格
collapseWhitespace: true,
//去除屬性引號
removeAttributeQuotes: true
},
//根據依賴引入chunk
chunksSortMode: "dependency"
})
]
});
module.exports = prodConf;
10. 創建 build/build.js
10.1 此文件是項目打包服務,用來構建一個全量壓縮包
10.2
"use strict";
//node for loading
const ora = require("ora");
// rm-rf for node
const rm = require("rimraf");
//console for node
const chalk = require("chalk");
//path for node
const path = require("path");
//webpack
const webpack = require("webpack");
//webpack production setting
const config = require("./webpack.prod.conf");
//指定刪除的文件
const rmFile = path.resolve(__dirname, "../public/static");
//build start loading
const spinner = ora("building for production...");
spinner.start();
//構建全量壓縮包!
rm(rmFile, function(err) {
if (err) throw err;
webpack(config, function(err, stats) {
spinner.stop();
if (err) throw err;
process.stdout.write(
stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + "\n\n"
);
if (stats.hasErrors()) {
console.log(chalk.red(" Build failed with errors.\n"));
process.exit(1);
}
console.log(chalk.cyan(" Build complete.\n"));
console.log(
chalk.yellow(
" Tip: built files are meant to be served over an HTTP server.\n" +
" Opening index.html over file:// won't work.\n"
)
);
});
});
10.3 創建好以上文件 我們就可以通過npm run build來打包我們的項目文件並部署上線啦。
11.大功告成!
通過以上步驟,一個spa版的vue腳手架就大功告成啦!
如果對一些細節不懂的可以留言或者上我的github查看
https://github.com/webfansplz...
最後還是那句話,如果有幫助到你,請給我star支持哈!
原文地址:https://segmentfault.com/a/1190000012736387
教你用webpack搭一個vue腳手架[超詳細講解和註釋!]