用 cooking 搭建一個多頁面易配置的 Vue 2 項目(進階篇)
通過 上一篇文章 的介紹,相信大家已經能用 cooking 配置一個較為完整的 Vue 項目。今天將通過一個多頁面的例子為大家介紹 cooking 的命令行工具 —— cooking-cli,同樣所需要的開發環境依舊是 Node 4+, npm 3+,同時我是在 macOS 下操作的。
搭建基礎項目
現在我們需要在上一篇文章配置的項目的基礎上,將它改造成支持多頁面的項目,其實我們可以直接通過 cooking 的命令行工具直接生成一個 Vue 項目。首先需要全局安裝 cooking-cli。
npm i cooking-cli -g --registry=https://registry.npm.taobao.org
先檢查下是不是使用的 npm 3+,如果不是先升級 npm 再安裝。完成後可以到你的目錄下執行下面指令創建一個目錄名 multiple-pages 的 Vue 項目,第一次執行需要安裝腳手架的依賴。
cooking create multiple-pages vue
如果沒有訪問較慢的話可以先配置下 npm 鏡像,然後再創建項目。
cooking config registry https://registry.npm.taobao.org
接下來會讓你選擇一些選項,我們這次選擇 Vue2 + bublé + 全局 cooking 的配置。
[?] Give your app a name: multiple-pages[?] Give your app a description: A vue project.[?] Private? Yes[?] What Vue version do you what? Vue 2[?] What ES2015+ compiler do you what to use? bublé (only use wepback 2)[?] What way use cooking do you want? Global cooking (webpack 2)[?] Need dev server? Yes[?] What CSS preprocessor do you want to use? Only CSS[?] Setup unit tests with Karma + Mocha? No[?] git repository:[?] author:[?] license: ISC[?] Continue? Yes
最後可以試試直接運行 npm run dev 看看能不能正常啟動。使用全局 cooking 的好處是可以減少項目的依賴,
多頁面項目分析
如果用 webpack 做 SPA 項目,通常是一個入口文件,第三方庫單獨打包,或者一些文件可以抽離出去通過 CDN 載入。如果換成多頁面,就需要多個入口文件,同時每個頁面用到的第三方庫也不相同,CDN 的配置也可能不一樣。那麼為了方便管理,我們可以將它們寫在一個配置文件里。
webpack 雖然支持配置多個 chunk,但是哪些頁面引入了哪些 common chunk 都需要手動維護,而且對於新手很容易犯錯。所以我打算依舊只配置一個 vendor,同時將第三方庫儘可能通過 CDN 的方式載入。這樣手動維護 CDN 列表比維護 chunk 清晰且容易許多。
這裡的 chunk 配置我使用 cooking 默認的,它會將 node_modules 內引用到的依賴都打包到 vendor 內,同時還有一個 manifest 用來保存 webpack 的 runtime,參考 vue webapck 模板。
設計配置文件
寫一個名叫 app.json 的配置文件,每個入口共享公共的 CDN 也可以配置私有的 CDN,還可以配置其他基本信息。
{ "pages": [ { "entry": "home", "title": "首頁", "cdn": {} }, { "entry": "admin", "title": "後台", "cdn": {} } ], "basePath": "./src/pages/", "cdn": { "js": [ "//cdn.jsdelivr.net/vue/2.0.0-rc.7/vue.min.js", "//cdn.jsdelivr.net/vuex/2.0.0-rc.5/vuex.min.js" ], "css": [] }, "externals": { "vue": "Vue", "vuex": "Vuex" }}
同時我們在 src/pages 目錄下創建 home 和 admin 目錄。每個目錄下創建一個 index.js 和 app.vue 文件。
index.js
import Vue from vueimport App from ./appnew Vue({ // eslint-disable-line el: #app, render: h => h(App)})
app.vue
<template> <div> <h1>首頁</h1> <p>A vue project.</p> </div></template><script> export default { name: app };</script>
配置 cooking
入口文件
接下來我們在生成的 cooking 配置文件上加工,這裡我們要傳入多入口的配置,從 app.json 里讀取 entry 的信息,通過 basePath 拼接成文件路徑。
var App = require(./app.json)var entries = function() { var result = {} App.pages.forEach(p => { result[p.entry] = path.resolve(App.basePath, p.entry) }) return result}cooking.set({ entry: entries()})
模板文件
所有入口的頁面我們都是通過 index.tpl 模板配置,只需要將公用 CDN 和私有 CDN 合併後拼接成 HTML 插入到模板內,同時引入入口文件和 vendor,通過 html-webpack-plugin 的配置選項,可以很方便的實現我們的需求。
var App = require(./app.json)var path = require(path)var merge = function(a, b) { return { css: (a.css || []).concat(b.css || []), js: (a.js || []).concat(b.js || []) }}var templates = function() { return App.pages.map(p => { return { title: p.title, filename: p.entry + .html, template: path.resolve(__dirname, index.tpl), cdn: merge(App.cdn, p.cdn), chunks: [vendor, manifest, p.entry] } })}cooking.set({ template: templates()})
模板文件也要改造一下。支持生成我們指定的 CDN 的 HTML 以及其他配置項。具體語法參考插件文檔。
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title><%= htmlWebpackPlugin.options.title %></title> <% for (var i in htmlWebpackPlugin.options.cdn.css) { %> <link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>"><% } %> </head> <body> <div id="app"></div> <% for (var i in htmlWebpackPlugin.options.cdn.js) { %> <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script><% } %> </body></html>
最終配置
最後我們可以優化一下配置,將生成配置的函數提取到另一個文件內,讓配置信息更清晰。那麼最終的配置內容如下。
var path = require(path)var cooking = require(cooking)var build = require(./build)cooking.set({ entry: build.entries(), dist: ./dist, template: build.templates(), devServer: { port: 8081, publicPath: /, }, clean: true, hash: true, sourceMap: true, chunk: true, publicPath: /dist/, extractCSS: true, alias: { src: path.join(__dirname, src) }, extends: [vue2, buble, lint, autoprefixer], externals: build.externals()})module.exports = cooking.resolve()
運行項目
我們直接通過 cooking 命令行啟動項目。
cooking watch -p
訪問 http://localhost:8081/home.html 或者 http://localhost:8081/admin.html 看效果。
最後我們通過 build 構建項目,最終打包文件在 dist 目錄里。
cooking build -p
總結
我會把上面的配置做成腳手架,可以直接通過 cooking init pages-vue 創建項目,當然只是做了最基礎的版本,還可以擴展許多內容:
- 比如配置某些頁面可以忽略全局的 CDN 文件
- 如果熟悉 chunk,那麼把 chunk 也抽離到配置文件里
- 給入口文件加開關,不一定每次啟動都打包所有入口文件
- 開發模式不使用 CDN,只有生產環境下才使用
如果感興趣的話歡迎來一起維護,加入更多新功能,腳手架地址。
這裡只是介紹了 cooking 的命令行工具最基礎的用法,還有許多實用的指令以及技巧還沒介紹,所以最後一篇,我將介紹一些使用上的技巧下一篇見。
---------
- GitHub - cooking-demo/multiple-pages-vue
- GitHub - cookingjs/slush-cooking-pages-vue: A multiple pages project for vue.
- GitHub - ElemeFE/cooking: 更易上手的前端構建工具
推薦閱讀: