本文的
webpack
配置是基於vue-cli
改良的,且面向有必定基礎的人css
vue init webpack
指令構建好一個初始的項目,刪除無關的東西,更改一下項目目錄以下src
static
中的文件清空 刪除package.json
中無關的依賴html
- "vue": "^2.4.2" - "vue-loader": "^13.0.4", - "vue-style-loader": "^3.0.1", - "vue-template-compiler": "^2.4.2",
build/vue-loader.conf.js
在src
中建立2個文件夾分別爲index
about
,在其中再建立3個文件index.html
index.css
index.js
目錄結構爲vue
build config src |———— views | |———— index | | |————— index.html | | |————— index.css | | |————— index.js | | | |———— index2 | |————— index.html | |————— index.css | |————— index.js |———— static // 存放靜態資源 |———— lib // 存放第三方庫 把每一個頁面當作一個模塊,這樣的模塊化方便項目管理,一眼瞄過去也比較清晰
更改webpack.base.conf.js
把與vue
相關的配置刪除node
module.exports = { resolve: { - extensions: ['.js', '.vue', '.json'], + extensions: ['.js', '.json'], alias: { - 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), } }, module: { rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - options: vueLoaderConfig - }, { test: /\.js$/, loader: 'babel-loader', - include: [resolve('src'), resolve('test')] + include: [resolve('src')] }, ........
在build/utils.js
中,更改配置。不得不說utils.js
中生成各類loader
確實寫的很棒,已經把全部的與css
相關的loader
涵蓋進去,若要使用,只須要安裝相關的loader
便可webpack
if (options.extract) { return ExtractTextPlugin.extract({ use: loaders, - fallback: 'vue-style-loader' + fallback: 'style-loader' }) } else { - return ['vue-style-loader'].concat(loaders) + return ['style-loader'].concat(loaders) }
咱們再也不須要vue-style-loader
只須要普通的style-loader
便可git
既然是多頁面,那麼就確定是有多個入口github
entry: { index: './src/index/index.js', about: './src/about/index.js' },
這裏科普一下,這裏的entry
路徑是相對於webpack
編譯時的基礎目錄context
(也就是package.json
所在目錄)。路徑的詳細解釋能夠參考這篇文章
頁面少的時候還ok,可是若是頁面多起來的時候所有都要本身手動去配置確實是挺麻煩的。因此這裏咱們來寫一段函數進行批量處理web
首先咱們在build
文件夾下新建文件pages.json
用於存放頁面的信息vue-cli
{ "root": "./src", // 頁面存放的目錄地址 "pages": [ // 頁面名, 打包生成的html,css,js文件也是這個名字 "index", "about" ] }
再在同個目錄下建立pages.conf.js
用來生成頁面的路徑npm
var config = require('./pages.json') var root = config.root var pages = config.pages function genPagesDir() { var dirs = {} for (var i = 0; i < pages.length; i++) { var a = pages[i] dirs[a] = `${root}/${a}` } return dirs } module.exports = genPagesDir()
跟着咱們回到webpack.base.conf.js
增長生成入口配置的函數
var pages = require('./pages.conf') ........ function genEntries() { var entries = {} for (var key in pages) { entries[key] = `${pages[key]}/index.js` } return entries }
而且把entry
配置進行更改, 這樣就大功告成
entry: genEntries()
入口的配置完成以後,就要進行模板的配置,這裏若是不瞭解html-webpack-plugin
的,能夠先去瞭解一下,單頁應用只有一個頁面因此模板就只有一個,那麼若是是多頁面應用,則可能會存在多個模板,多個模板就必須配置多個HtmlWebpackPlugin
。說簡單點就是,有n
個頁面,就要在plugins
中寫n
個
new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true }),
因此這裏就必需要再寫一個批量生成的函數,和生成入口配置是一個道理的。
var pages = require('./pages.conf') ....... function genHtmlWebpackPlugin() { var arr = []; for (var key in pages) { arr.push(new HtmlWebpackPlugin({ filename: `${key}.html`, template: `${pages[key]}/index.html`, inject: true, chunks: [`${key}`] // chunk爲該頁面要包含的js文件 })) } return arr; } module.exports = merge(baseWebpackConfig, { .... plugins: [ .... - new HtmlWebpackPlugin({ - filename: 'index.html', - template: 'index.html', - inject: true - }), .... + ].concat(genHtmlWebpackPlugin()) })
filename
是相對於output.publicPath
, 在dev-server
中則是相對於其assetsPublicPath
, 保持這兩者相同就是爲了更方便的配置 template
則是相對於context
(也就是上文提到的)chunks
必須寫,否則頁面將會把全部打包後的js文件引入
webpack.prod.conf.js
的配置也是相似的,這裏再也不贅述,須要注意的是chunks
須要包含vendor
,manifest
。 還有filename
要用打包目錄dist
filename: `${config.build.assetsRoot}/${key}.html`
pages.json
中添加新增的頁面。仔細想一想好像仍是挺麻煩的。那咱們自個寫個指令來自動實現這些功能吧!build
中建立文件create.js
package.json
中添加指令"create": "node build/create.js"
開始碼代碼~
咱們的預想是經過npm run create filename
指令完成上述一系列步驟,那麼咱們就要知道如何去在create.js
中去讀取這個filename
。 其實這個參數就在變量process
中,process
是node
的一個全局變量,這裏不展開來說,有興趣的能夠本身去了解。 咱們能夠試着打印一下process.argv
的內容。
在create.js
中增長如下代碼,而後執行npm run create about
, 查看輸出
var dirname = process.argv; console.log(dirname)
能夠看到process.argv
中分別包含了指令的3個部分node
,create.js
,about
因此,process.argv[2]
就是咱們想要的dirname
建立文件那就須要用到node
的fs
, 經過fs.mkdir
來建立目錄,再經過fs.writeFile
來建立文件。固然咱們還須要寫一些異常處理的代碼, 當指令沒有輸入filename
或文件夾已存在時,進行提示,chalk
可讓咱們的cmd輸出看起來更加美觀一些。 下面爲代碼
var fs = require('fs') var chalk = require('chalk') var root = require('./pages.json').root var dirname = process.argv[2] var path = `${root}/${dirname}` var htmlTemplate = `<!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>title</title> </head> <body> </body> </html>` if (!dirname) { console.error(chalk.bgRed('Please input the dirname !!!\n')) return } if (fs.existsSync(path)) { console.error(chalk.bgRed('File is already exists !!!\n')) return } function throwErr (err) { if (err) { throw err } } fs.mkdir(path , (err) => { if (!err) { fs.writeFile(`${path}/index.html`, htmlTemplate, throwErr); fs.writeFile(`${path}/index.js`, '', throwErr); fs.writeFile(`${path}/index.css`, '', throwErr); console.log(chalk.bgGreen(' Create success.\n')); } })
到這已經完成了文件的建立功能。
接下來要寫更新pages.json
的代碼,經過fs.readFile
把pages.json
的內容讀取進來,讀取進來的是json字符串,那麼使用JSON.parse
便可將其轉爲對象,而後再往pages
中增長新的內容,再而後使用JSON.stringify
將其轉回字符串寫回到文件中。大功告成
function updatePages() { var path = 'build/pages.json' var rc = JSON.parse(fs.readFileSync(path, {encoding: 'utf-8'})) rc.pages = rc.pages.concat(dirname) var wc = JSON.stringify(rc) fs.writeFileSync(path, wc) } // 記得在建立完3個文件以後updatePages()進行調用
至此全部的代碼已寫完了。以後就可使用懶人指令進行建立文件了。只不過刪除的時候不能自動更新,須要本身到pages.json
中進行刪除。
以後還會再寫多一片文章,經過使用這個webpack配置來對舊項目進行重構。新人第一篇文章,有不對的地方望指出。_(:з」∠)_