摘要:安裝安裝完成之后,你應(yīng)該可以使用了,方式如下上述命令應(yīng)該自動在瀏覽器中打開。
前言
webpack2和vue2已經(jīng)不是新鮮東西了,滿大街的文章在講解webpack和vue,但是很多內(nèi)容寫的不是很詳細,對于很多個性化配置還是需要自己過一遍文檔。Vue官方提供了多個vue-templates,基于vue-cli用官方的webpack模板居多,不過對于很多人來說,官方的webpack模板的配置還是過于復雜,對于我們了解細節(jié)實現(xiàn)不是很好,所以想自己從零開始搭建一個模板工程,也順便重新認識一下webpack和vue工程化的細節(jié)。
webpack 核心概念Webpack 是當下最熱門的前端資源模塊化管理和打包工具。它可以將許多松散的模塊按照依賴和規(guī)則打包成符合生產(chǎn)環(huán)境部署的前端資源。還可以將按需加載的模塊進行代碼分隔,等到實際需要的時候再異步加載。通過 loader 的轉(zhuǎn)換,任何形式的資源都可以視作模塊,比如 CommonJs 模塊、 AMD 模塊、 ES6 模塊、CSS、圖片、 JSON、Coffeescript、 LESS 等。
官方網(wǎng)站:https://webpack.js.org/
安裝在開始前,先要確認你已經(jīng)安裝Node.js的最新版本。使用 Node.js 最新的 LTS 版本,是理想的起步。使用舊版本,你可能遇到各種問題,因為它們可能缺少 webpack 功能或缺少相關(guān) package 包。
本地局部安裝:
# 安裝 latest release npm install --save-dev webpack # 簡寫模式 npm install -D webpack # 安裝特定版本 npm install --save-dev webpack@
全局安裝:
npm install -g webpack
注意:不推薦全局安裝 webpack。這會鎖定 webpack 到指定版本,并且在使用不同的 webpack 版本的項目中可能會導致構(gòu)建失敗。但是全局安裝可以在命令行調(diào)用 webpack 命令。
【補充】npm install 安裝模塊參數(shù)說明:
-g, --global 全局安裝(global) -S, --save 安裝包信息將加入到dependencies(生產(chǎn)階段的依賴) -D, --save-dev 安裝包信息將加入到devDependencies(開發(fā)階段的依賴),所以開發(fā)階段一般使用它 -O, --save-optional 安裝包信息將加入到optionalDependencies(可選階段的依賴) -E, --save-exact 精確安裝指定模塊版本
npm 相關(guān)的更多命令參考這篇文章:npm 常用命令詳解
然后在根目錄下創(chuàng)建一個 webpack.config.js 文件后,你可以通過配置定義webpack的相關(guān)操作。
入口(Entry)入口起點告訴 webpack 從哪里開始,并遵循著依賴關(guān)系圖表知道要打包什么??梢詫⒛鷳?yīng)用程序的入口起點認為是根上下文(contextual root)或 app 第一個啟動文件。
單個入口(簡寫)語法:
用法:entry: string|Array
webpack.config.js:
module.exports = { entry: "./src/main.js" };
對象語法:
用法:entry: {[entryChunkName: string]: string|Array
webpack.config.js:
module.exports = { entry: { app: "./src/main.js", vendor: ["vue"] } };
這里我們將vue作為庫vendor打包,業(yè)務(wù)邏輯代碼作為app打包,實現(xiàn)了多個入口,同時也可以將多個頁面分開打包。
多頁面應(yīng)用程序通常使用對象語法構(gòu)建。對象語法是“可擴展的 webpack 配置”,可重用并且可以與其他配置組合使用。這是一種流行的技術(shù),用于將關(guān)注點(concern)從環(huán)境(environment)、構(gòu)建目標(build target)、運行時(runtime)中分離。然后使用專門的工具(如webpack-merge)將它們合并。
注:vue-cli 生成的模板中build文件夾下有四個配置文件:
webpack.base.conf.js:基本配置
webpack.dev.conf.js:開發(fā)階段配置
webpack.prod.conf.js:準生產(chǎn)階段配置
webpack.test.conf.js:測試配置
后三個文件通過webpack-merge插件合并了基本配置,將不同環(huán)境下的配置拆分多個文件,這樣更加方便管理。
出口(Output)將所有的資源(assets)歸攏在一起后,還需要告訴 webpack 在哪里打包應(yīng)用程序。webpack 的 output 屬性描述了如何處理歸攏在一起的代碼(bundled code)。output 選項控制 webpack 如何向硬盤寫入編譯文件。注意,即使可以存在多個入口起點,但只指定一個輸出配置。
在 webpack 中配置output 屬性的最低要求是,將它的值設(shè)置為一個對象,包括以下兩點:
output.filename:編譯文件的文件名;
output.path對應(yīng)一個絕對路徑,此路徑是你希望一次性打包的目錄。
單個入口:
const path = require("path"); module.exports = { entry: "./src/app.js", output: { filename: "bundle.js", path: path.resolve(__dirname, "build") //__dirname + "/build" } }
多個入口:
如果你的配置創(chuàng)建了多個 "chunk"(例如使用多個入口起點或使用類似CommonsChunkPlugin 的插件),你應(yīng)該使用以下的替換方式來確保每個文件名都不重復。
[name] 被 chunk 的 name 替換。
[hash] 被 compilation 生命周期的 hash 替換。
[chunkhash] 被 chunk 的 hash 替換。
const path = require("path"); module.exports = { entry: { app: "./src/main.js", vendor: ["vue"] }, output: { filename: "[name].js", path: path.resolve(__dirname, "build") } } // 寫入到硬盤:./build/app.js, ./build/vendor.js加載器(Loaders)
loader 用于對模塊的源代碼進行轉(zhuǎn)換。loader 可以使你在 require() 或"加載"模塊時預處理文件。因此,loader 類似于其他構(gòu)建工具中“任務(wù)(task)”,并提供了處理前端構(gòu)建步驟的強大方法。loader 可以將文件從不同的語言(如 TypeScript)轉(zhuǎn)換為 JavaScript,或?qū)?nèi)聯(lián)圖像轉(zhuǎn)換為 data URL。loader 甚至允許你在 JavaScript 中 require() CSS文件!
在你的應(yīng)用程序中,有三種方式使用 loader:
通過webpack.config.js配置
使用 require 語句中顯示使用
通過 webpack CLI
這里我們主要說明一下使用webpack.config.js配置,使用loader需要在module的rules下配置相應(yīng)的規(guī)則,以css-loader的webpack.config.js為例說明:
module.exports = { module: { rules: [ {test: /.css$/, use: "css-loader"} ] } };
這三種配置方式等效:
{test: /.css$/, use: "css-loader"} {test: /.css$/, loader: "css-loader",options: { modules: true }} {test: /.css$/, use: { loader: "css-loader", options: { modules: true } }}
注:loader/query可以和options可以在同一級使用,但是不要使用use和options在同一級使用。
CSS樣式分離為了用 webpack 對 CSS 文件進行打包,你可以像其它模塊一樣將 CSS 引入到你的 JavaScript 代碼中,同時用css-loader(像 JS 模塊一樣輸出 CSS),也可以選擇使用ExtractTextWebpackPlugin(將打好包的 CSS 提出出來并輸出成 CSS 文件)。
引入 CSS:
import "bootstrap/dist/css/bootstrap.css";
安裝css-loader和style-loader:
npm install --save-dev css-loader style-loader
在 webpack.config.js 中配置如下:
module.exports = { module: { rules: [{ test: /.css$/, use: ["style-loader", "css-loader"] }] } }資源路徑處理
因為.png等圖片文件不是一個 JavaScript 文件,你需要配置 Webpack 使用file-loader或者url-loader去處理它們。使用它們的好處:
file-loader 可以指定要復制和放置資源文件的位置,以及如何使用版本哈希命名以獲得更好的緩存。此外,這意味著 你可以就近管理你的圖片文件,可以使用相對路徑而不用擔心布署時URL問題。使用正確的配置,Webpack 將會在打包輸出中自動重寫文件路徑為正確的URL。
url-loader 允許你有條件將文件轉(zhuǎn)換為內(nèi)聯(lián)的 base-64 URL(當文件小于給定的閾值),這會減少小文件的 HTTP 請求。如果文件大于該閾值,會自動的交給 file-loader 處理。
安裝 file-loader 和 url-loader:
npm install --save-dev file-loader url-loader
配置說明:
{ test: /.(png|jpe?g|gif|svg)(?.*)?$/, loader: "url-loader", options: { limit: 10000, name: "img/[name]_[hash:7].[ext]" } }, { test: /.(woff2?|eot|ttf|otf)(?.*)?$/, loader: "url-loader", options: { limit: 10000, name: "fonts/[name].[hash:7].[ext]" } }插件(Plugins)
由于 loader 僅在每個文件的基礎(chǔ)上執(zhí)行轉(zhuǎn)換,而插件(plugins)最常用于(但不限于)在打包模塊的“compilation”和“chunk”生命周期執(zhí)行操作和自定義功能(查看更多)。webpack 的插件系統(tǒng)極其強大和可定制化。
想要使用一個插件,你只需要 require() 它,然后把它添加到 plugins 數(shù)組中。多數(shù)插件可以通過選項(option)自定義。你也可以在一個配置文件中因為不同目的而多次使用同一個插件,你需要使用 new 創(chuàng)建實例來調(diào)用它。
生產(chǎn)環(huán)境構(gòu)建對于Vue生產(chǎn)環(huán)境構(gòu)建過程中壓縮應(yīng)用代碼和使用Vue.js 指南 - 刪除警告去除 Vue.js 中的警告,這里我們參考vue-loader文檔中的配置說明:
if (process.env.NODE_ENV === "production") { // http://vue-loader.vuejs.org/zh-cn/workflow/production.html module.exports.plugins = (module.exports.plugins || []).concat([ new webpack.DefinePlugin({ "process.env": { NODE_ENV: ""production"" } }), new webpack.optimize.UglifyJsPlugin({ sourceMap: false, compress: { warnings: false } }), new webpack.LoaderOptionsPlugin({ minimize: true }) ]) }
顯然我們不想在開發(fā)過程中使用這些配置,所以這里我們需要使用環(huán)境變量動態(tài)構(gòu)建,我們也可以使用兩個分開的 Webpack 配置文件,一個用于開發(fā)環(huán)境,一個用于生產(chǎn)環(huán)境,類似于vue-cli中使用 webpack-merge 合并配置的方式。
可以使用 Node.js 模塊的標準方式:在運行 webpack 時設(shè)置環(huán)境變量,并且使用 Node.js 的process.env來引用變量。NODE_ENV變量通常被視為事實標準(查看這里)。使用cross-env包來跨平臺設(shè)置(cross-platform-set)環(huán)境變量。
安裝cross-env:
npm install --save-dev cross-env
設(shè)置package.json中的scripts字段:
"scripts": { "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot", "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" }
這里我們使用了cross-env插件,cross-env使得你可以使用單個命令,而無需擔心為平臺正確設(shè)置或使用環(huán)境變量。
模塊熱替換模塊熱替換功能會在應(yīng)用程序運行過程中替換、添加或刪除模塊,而無需重新加載頁面。這使得你可以在獨立模塊變更后,無需刷新整個頁面,就可以更新這些模塊,極大地加速了開發(fā)時間。
這里我們使用webpack-dev-server插件,webpack-dev-server 為你提供了一個服務(wù)器和實時重載(live reloading)功能。webpack-dev-server是一個小型的node.js Express服務(wù)器,它使用webpack-dev-middleware中間件來為通過webpack打包生成的資源文件提供Web服務(wù)。它還有一個通過Socket.IO連接著webpack-dev-server服務(wù)器的小型運行時程序。webpack-dev-server發(fā)送關(guān)于編譯狀態(tài)的消息到客戶端,客戶端根據(jù)消息作出響應(yīng)。
安裝 webpack-dev-server:
npm install --save-dev webpack-dev-server
安裝完成之后,你應(yīng)該可以使用 webpack-dev-server 了,方式如下:
webpack-dev-server --open
上述命令應(yīng)該自動在瀏覽器中打開 http://localhost:8080。
webpack.config.js配置:
module.exports = { ... devServer: { historyApiFallback: true, // 任意的 404 響應(yīng)都替代為 index.html hot: true, // 啟用 webpack 的模塊熱替換特性 inline: true // 啟用內(nèi)聯(lián)模式 }, plugins: [ new webpack.HotModuleReplacementPlugin() ] ... }
更多的配置說明可以看文檔:DevServer
動態(tài)生成 html 文件該插件將為你生成一個HTML5文件,其中包括使用script標簽的body中的所有webpack包,也就是我們不需要手動通過script去引入打包生成的js,特別是如果我們生成的文件名是動態(tài)變化的,使用這個插件就可以輕松的解決,只需添加插件到您的webpack配置如下:
const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { ... plugins: [ new HtmlWebpackPlugin({ filename: "index.html", template: "index.html", inject: true }) ] ... }提取 CSS 文件
extract-text-webpack-plugin是一個 可以將 *.vue 文件內(nèi)的