用 cooking 搭建一個多頁面易配置的 Vue 2 項目(進階篇)

經過 上一篇文章 的介紹,相信你們已經能用 cooking 配置一個較爲完整的 Vue 項目。今天將經過配置一個多頁面的例子爲你們介紹 cooking 的命令行工具 —— cooking-cli,一樣所須要的開發環境依舊是 Node 4+, npm 3+,同時我是在 macOS 下操做的。javascript

搭建基礎項目

如今咱們須要在上一篇文章配置的項目的基礎上,將它改形成支持多頁面的項目,其實咱們能夠直接經過 cooking 的命令行工具直接生成一個 Vue 項目。首先須要全局安裝 cooking-clicss

npm i cooking-cli -g --registry=https://registry.npm.taobao.org

先檢查下是否是使用的 npm 3+,若是不是先升級 npm 再安裝。完成後能夠到你的項目目錄下執行下面指令建立一個目錄名 multiple-pages 的 Vue 項目,第一次執行須要安裝腳手架的依賴。html

cooking create multiple-pages vue

若是沒有訪問較慢的話能夠先配置下 npm 鏡像,而後再建立項目。vue

cooking config registry https://registry.npm.taobao.org

接下來會讓你選擇一些選項,咱們此次選擇 Vue2 + bublé + 全局 cooking 的配置。java

[20:01:54] Starting 'cooking-vue:default'...
[?] 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 的好處是能夠減小項目的依賴,node

多頁面項目分析

若是用 webpack 作 SPA 項目,一般是一個入口文件,第三方庫單獨打包,或者一些文件能夠抽離出去經過 CDN 加載。若是換成多頁面,就須要多個入口文件,同時每一個頁面用到的第三方庫也不相同,CDN 的配置也可能不同。那麼爲了方便管理,咱們能夠將它們寫在一個配置文件裏。webpack

webpack 雖然支持配置多個 chunk,可是哪些頁面引入了哪些 common chunk 都須要手動維護,並且對於新手很容易犯錯。因此我打算依舊只配置一個 vendor,同時將第三方庫儘量經過 CDN 的方式加載。這樣手動維護 CDN 列表比維護 chunk 清晰且容易許多。git

這裏的 chunk 配置我使用 cooking 默認的,它會將 node_modules 內引用到的依賴都打包到 vendor 內,同時還有一個 manifest 用來保存 webpack 的 runtime,參考 vue webapck 模板github

設計配置文件

寫一個名叫 app.json 的配置文件,每一個入口共享公共的 CDN 也能夠配置私有的 CDN,還能夠配置其餘基本信息。web

{
  "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 目錄下建立 homeadmin 目錄。每一個目錄下建立一個 index.jsapp.vue 文件。

index.js

import Vue from 'vue'
import App from './app'

new 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 path = require('path')

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 構建項目。

cooking build -p

總結

我會把上面的配置作成腳手架,能夠直接經過 cooking init pages-vue 建立項目,固然只是作了最基礎的版本,還能夠擴展許多內容:

  • 好比配置某些頁面能夠忽略全局的 CDN 文件

  • 若是熟悉 chunk,那麼把 chunk 也抽離到配置文件裏

  • 給入口文件加開關,不必定每次啓動都打包全部入口文件

  • 開發模式不使用 CDN,只有生產環境下才使用

若是感興趣的話歡迎來一塊兒維護,加入更多新功能。

這裏只是介紹了 cooking 的命令行工具最基礎的用法,還有許多實用的指令以及技巧還沒介紹,因此下一篇見。

相關文章
相關標籤/搜索