apollo-build

apollo-build 是(shì)一(yī / yì /yí)個(gè)構建工具,提供 serverbuildbuildDll 和(hé / huò) test 四個(gè)命令,分别用于(yú)本地(dì / de)調試、構建、打包 dll 和(hé / huò)測試,并且提供了(le/liǎo)特别易用的(de) mock 功能。命令行體驗和(hé / huò) create-react-app 一(yī / yì /yí)緻,配置略有不(bù)同,比如默認開啓 css modules然後還提供了(le/liǎo) [JSON 格式的(de)配置方式]

快速開始

首先,我們會幫您搭建 npm 私有倉庫。

安裝

# --registry 爲(wéi / wèi) npm 私有倉庫的(de)地(dì / de)址
$ npm i apollo-build -g --registry=http://xxx.x.x.x

使用

本地(dì / de)開發

$ apollo-build server

打包發布

$ apollo-build build

打包 dll 靜态文件

$ apollo-build buildDll

測試,默認會跑 ./test 目錄下的(de)所有文件

$ apollo-build test

特性

  • HMR (熱替換)

CSS 在(zài)開發模式下會走 style-loader (被内嵌在(zài) JavaScript 文件中),所以(yǐ)隻要(yào / yāo)保證 JavaScript 的(de)熱更新,即可實現 CSS 的(de)熱更新。

如果大(dà)家使用 apollo ,配上(shàng) babel-plugin-dva-hmr 即可實現 routes 和(hé / huò) components 以(yǐ)及相關 CSS 修改的(de)熱更新,其他(tā)修改會自動刷新頁面。

"env": {
  "development": {
    "extraBabelPlugins": ["dva-hmr"]
  }
}
  • Mock

server 支持 mock 功能,默認讀取根目錄下的(de).roadhogrc.mock.js文件

比如:

export default {
  // 支持值爲(wéi / wèi) Object 和(hé / huò) Array
  'GET /api/users': { users: [1,2] },

  // GET POST 可省略
  '/api/users/1': { id: 1 },

  // 支持自定義函數,API 參考 express@4
  'POST /api/users/create': (req, res) => { res.end('OK'); },

  // Forward 到(dào)另一(yī / yì /yí)個(gè)服務器
  'GET /assets/*': 'https://assets.online/',

  // Forward 到(dào)另一(yī / yì /yí)個(gè)服務器,并指定子(zǐ)路徑
  // 請求 /someDir/0.0.50/index.css 會被代理到(dào) https://g.alicdn.com/tb-page/taobao-home, 實際返回 https://g.alicdn.com/tb-page/taobao-home/0.0.50/index.css
  'GET /someDir/(.*)': 'https://g.alicdn.com/tb-page/taobao-home',
};
  • 智能重啓

配置文件修改的(de)修改會觸發 server 的(de)自動重啓,會觸發重啓的(de)文件有:

  • .roadhogrc
  • .roadhogrc.js
  • .roadhogrc.mock.js
  • theme 配置指定的(de)文件

配置

關于(yú)配置的(de)一(yī / yì /yí)些基本概念:

  • 配置存于(yú) .roadhogrc 文件中(如果你不(bù)喜歡 JSON 配置,可以(yǐ)用 .roadhogrc.js 以(yǐ) JS 的(de)方式編寫,支持 ES6)
  • 格式爲(wéi / wèi) JSON,允許注釋
  • 支持通過 webpack.config.js 以(yǐ)編碼的(de)方式進行配置,但不(bù)推薦,升級可能會引起兼容問題。使用時(shí)會給予警告。(webpack.config.js 本身的(de)編寫支持 ES6,會通過 babal-register 做一(yī / yì /yí)層轉換。)
/**
 * webpack.config.js  例子(zǐ)
 * @param webpackConfig  webpack配置文件
 * @param env process env
 * @param webpack  webpack對象,用于(yú)部分插件配置
 * @param args 命令行參數對象
 * @returns {*}
 */
module.exports = function (webpackConfig, env, webpack, args) {
  //覆蓋默認的(de)webpackConfig
  return webpackConfig
}

默認配置:

{
  "entry": "src/index.js",
  "disableCSSModules": false,
  "cssModulesExclude": [],
  "publicPath": "/",
  "outputPath": "./dist",
  "extraBabelPlugins": [],
  "extraBabelPresets": [],
  "extraPostCSSPlugins": [],
  "sass": false,
  "hash": true,
  "autoprefixer": null,
  "proxy": null,
  "externals": null,
  "library": null,
  "libraryTarget": "var",
  "define": null,
  "env": null,
  "theme": null,
  "templatePath" : null,
  "commonChunks": null,
  "publicFilePath": "public"
}

entry

指定 webpack 入口文件,支持對象、字符串、 glob 格式以(yǐ)及數組格式

如果你的(de)項目是(shì)單入口類型,直接使用字符串定位路徑到(dào)入口文件即可

如果你的(de)項目是(shì)多入口類型,并希望按照模塊目錄來(lái)輸出(chū)類似src/project1/index.js 和(hé / huò) src/project2/index.js 的(de)文件作爲(wéi / wèi)入口。可以(yǐ)這(zhè)樣配:

 "entry": {
    "project1/index": "./src/project1/index.js",
    "project2/index": "./src/project2/index.js",
  },

這(zhè)樣的(de)最終build打包的(de)輸出(chū)會是(shì):

/dist
  -project1
    -index.hash.js
  -project2     
    -index.hash.js
  • 注意需要(yào / yāo)結合 templatePath 的(de)多入口配置和(hé / huò)對應多入口模闆一(yī / yì /yí)起使用比較好,否則無法正确自動生成 html 入口文件,需要(yào / yāo)手工去更新 html 入口文件
  • 注意 static 靜态資源的(de)引入相對路徑會因爲(wéi / wèi)多入口打包路徑的(de)不(bù)同而(ér)變化
  • 多入口具體使用可以(yǐ)參考下面多入口的(de)使用說(shuō)明

disableCSSModules

禁用 CSS Modules。最好别關,熟悉并使用他(tā)後,你會發現寫樣式簡單了(le/liǎo)很多。

cssModulesExclude

支持 CSSModules 混用,通過 cssModulesExclude 可指定不(bù)需要(yào / yāo)走 CSSModules 的(de)文件列表。

"cssModulesExclude": [
  './src/a.css',
  './src/b.less',
]

hash

使用 hash 文件名。

"hash": true

publicPath

配置生産環境的(de) publicPath,開發環境下永遠爲(wéi / wèi) /

outputPath

配置輸出(chū)路徑,默認是(shì) ./dist

publicFilePath

配置 build 和(hé / huò) server 模式下要(yào / yāo)拷貝到(dào) outputPath 根目錄下的(de)文件路徑,默認是(shì) public.

extraBabelPlugins

配置額外的(de) babel plugin。babel plugin 隻能添加,不(bù)允許覆蓋和(hé / huò)删除。

比如,同時(shí)使用 antd, dva 時(shí),通常需要(yào / yāo)這(zhè)麽配:

"extraBabelPlugins": [
  "transform-runtime",
  "dva-hmr",
  ["import", { "libraryName": "antd", "libraryDirectory": "lib", "style": "css" }]
]

同時(shí)安裝相關依賴:

$ npm i babel-plugin-transform-runtime babel-plugin-import babel-plugin-dva-hmr --save-dev
$ npm i babel-runtime --save

注意:這(zhè)麽配還有個(gè)問題,dva-hmr 是(shì)開發環境的(de)插件,如果 build 時(shí)也(yě)用上(shàng)就(jiù)會打出(chū)冗餘代碼。解決方案詳見 #env

extraBabelPresets

配置額外的(de) babel preset

比如:

"extraBabelPresets": ["stage-1"]

同時(shí)安裝相關依賴:

$ npm i babel-preset-stage-1 --save-dev

extraPostCSSPlugins

配置額外的(de) postcss 插件。

注意:由于(yú) postcss 的(de)插件是(shì)以(yǐ)函數的(de)方式進行配置的(de),所以(yǐ)這(zhè)個(gè)配置隻能在(zài) .roadhogrc.js 裏使用。

比如:

extraPostCSSPlugins: [
  pxtorem({
    rootValue: 100,
    propWhiteList: [],
  }),
],

autoprefixer

配置 autoprefixer 參數,詳見 autoprefixer 和(hé / huò) browserslist

比如,如果是(shì)做移動端的(de)開發,可以(yǐ)配成:

"autoprefixer": {
  "overrideBrowserslist": [
    "iOS >= 8", "Android >= 4"
  ]
}

sass

支持 sass,值爲(wéi / wèi) node-sass 的(de)配置參數。

注意:開啓 sass 支持需在(zài)項目代碼中安裝 node-sass 和(hé / huò) sass-loader 兩個(gè)依賴。

因爲(wéi / wèi)安裝 node-sass 需要(yào / yāo)下載 github 上(shàng)面的(de)一(yī / yì /yí)些庫,因此容易失敗,如果失敗可以(yǐ)查看下面的(de)鏈接 node sass 安裝失敗解決方法

proxy

配置代理,詳見 webpack-dev-server#proxy

如果要(yào / yāo)代理請求到(dào)其他(tā)服務器,可以(yǐ)這(zhè)樣配:

"proxy": {
  "/api": {
    "target": "http://jsonplaceholder.typicode.com/",
    "changeOrigin": true,
    "pathRewrite": { "^/api" : "" }
  }
}

然後訪問 /api/users 就(jiù)能訪問到(dào) http://jsonplaceholder.typicode.com/users 的(de)數據。

如果要(yào / yāo)做數據 mock,可以(yǐ)考慮和(hé / huò) json-server 結合使用,把 /api 代理到(dào) json-server 啓動的(de)端口。

externals

配置 webpack 的(de) externals 屬性。

library

配置 webpack 的(de) library 屬性。

libraryTarget

配置 webpack 的(de) libraryTarget 屬性。

define

配置 webpack 的(de) DefinePlugin 插件,define 的(de)值會自動做 JSON.stringify 處理。

env

針對特定的(de)環境進行配置。server 的(de)環境變量是(shì) development,build 的(de)環境變量是(shì) production

比如:

"extraBabelPlugins": ["transform-runtime"],
"env": {
  "development": {
    "extraBabelPlugins": ["dva-hmr"]
  }
}

這(zhè)樣,開發環境下的(de) extraBabelPlugins 是(shì) ["transform-runtime", "dva-hmr"],而(ér)生産環境下是(shì) ["transform-runtime"]

theme

配置主題,實際上(shàng)是(shì)配 less 的(de) modifyVars。支持 Object 和(hé / huò)文件路徑兩種方式的(de)配置。

比如:

"theme": {
  "@primary-color": "#1DA57A"
}

或者,

"theme": "./node_modules/abc/theme-config.js"

svgSpriteLoaderDirs

配置一(yī / yì /yí)個(gè)路徑數組, 該路徑下的(de) svg 文件會全部交給 svg-sprite-loader 處理

// npm i antd-mobile -S
const path = require('path');
const svgSpriteDirs = [
  require.resolve('antd-mobile').replace(/warn\.js$/, ''), // antd-mobile 内置svg
  path.resolve(__dirname, 'src/my-project-svg-foler'),  // 業務代碼本地(dì / de)私有 svg 存放目錄
];

export default {
  // ...
  svgSpriteLoaderDirs: svgSpriteDirs,
  //...
}

templatePath 支持輸入是(shì)字符串或者是(shì)對象。 對于(yú)普通的(de)單頁應用,直接傳入字符串指定模闆路徑即可。 對于(yú)多入口應用,需要(yào / yāo)傳入類似下面的(de)對象:

"templatePath": [{
  template: "src/project1/index.ejs",
  filename: 'project1/index.htm',
  inject: false,
  chunks: ['project1/index'],
},
{
  template: "src/project2/index.ejs",
  filename: 'project2/index.htm',
  inject: false,
  chunks: ['project2/index'],
}],

參數信息可以(yǐ)參考 html-webpack-template

  • 注意多入口應用的(de) template 一(yī / yì /yí)般需要(yào / yāo)關閉默認的(de) inject, 需要(yào / yāo)使用定制化的(de)模闆來(lái)保證 chunks 可以(yǐ)正确插入,多入口具體使用可以(yǐ)參考下面多入口的(de)使用說(shuō)明
  • 注意 static 靜态資源的(de)引入相對路徑會因爲(wéi / wèi)打包路徑的(de)不(bù)同而(ér)變化

commonChunks

傳入數組,用來(lái)指定把相應的(de)包和(hé / huò)對應依賴抽取成單獨的(de)文件。

  • name 字符串 代表 chunk名,也(yě)對應最後生成的(de)文件名。
  • chunks 數組 代表需要(yào / yāo)抽取的(de)包名

如下配置,會從 appllo 和(hé / huò) react 依賴中生成 stable.[hash:8].js 和(hé / huò) react.[hash:8].js

 "commonChunks": [{
    "name": "stable",
    "chunks": ["apollo"]
  }, {
    "name" : "react",
    "chunks": ["react"]
  }]

dllPlugin 配置是(shì)否需要(yào / yāo)使用 webpack dll plugin 。默認會把 node_modules 裏面的(de)引用庫到(dào) node_modules/roadhog-dlls 。可以(yǐ)使用 include 來(lái) 包含更多的(de)庫,庫的(de)引用路徑爲(wéi / wèi) app 當前路徑以(yǐ)及 node_modules , 使用 exclude 來(lái)去掉包含的(de)庫。 注意:庫的(de) package.json 裏面沒有包含有效入口的(de)庫以(yǐ)及 css 庫無法引入到(dào) dll中,例如下面的(de)例子(zǐ),exclude 的(de)庫是(shì)無法編成 dll 的(de)。

"dllPlugin": {
  include:[],
  exclude:['babel-runtime','apollo-component-mobile','normalize.css']
},

環境變量

環境變量可配置一(yī / yì /yí)些參數,包括:

  • PORT,端口号,默認 8000
  • HOST,默認 localhost
  • HTTPS,是(shì)否開啓 https,默認關閉
  • BROWSER,設爲(wéi / wèi) none 時(shí)不(bù)自動打開浏覽器
  • CLEAR_CONSOLE,設爲(wéi / wèi) none 時(shí)清屏

比如,使用 3000 端口開啓服務器可以(yǐ)這(zhè)樣:

// OS X, Linux
$ PORT=3000 apollo-build server

// Windows (cmd.exe)
$ set PORT=3000&&apollo-build server

命令行參數

apollo-build server

$ apollo-build server -h
Usage: apollo-build server [options]

Options:
  -h      顯示幫助      [boolean]
  --ie8   支持 IE8      [boolean] [default: false]

apollo-build build

$ apollo-build build -h
Usage: apollo-build build [options]

Options:
  --debug            不(bù)壓縮構建                        [boolean] [default: false]
  --watch, -w        監聽文件變化并重構建               [boolean] [default: false]
  --output-path, -o  指定輸出(chū)路徑                      [string] [default: null]
  --analyze          可視化分析 webpack bundle         [boolean] [default: false]
  --ie8              支持 IE8                          [boolean] [default: false]
  --sourcemap        構建時(shí)生成 sourcemap              [boolean] [default: false]
  --dropconsole      構建時(shí)移除 console 日志            [boolean] [default: false]
  -h                 顯示幫助                          [boolean]

apollo-build buildDll

把通用庫打成 dll,再使用 apollo-build server 的(de)時(shí)候能夠減少編譯時(shí)間,具體詳情可以(yǐ)參考 webpack dll plugin

$ apollo-build buildDll -h
Usage: apollo-build buildDll [options]

Options:
  -h      顯示幫助                                      [boolean]

apollo-build test

$ apollo-build test -h
Usage: apollo-build test [options] [mocha-options]

Options:
  --coverage  輸出(chū)覆蓋率                                 [boolean] [default: false]
  -h          顯示幫助                                   [boolean]

使用 public 目錄

我們約定默認在(zài) public 目錄下的(de)文件會在(zài) server 和(hé / huò) build 時(shí)被自動 copy 到(dào)輸出(chū)目錄(默認是(shì) ./dist)下。所以(yǐ)可以(yǐ)在(zài)這(zhè)裏存放 favicon, iconfont, html, html 裏引用的(de)图片等。 注意約定 public/opt 下面的(de) js類型文件會在(zài) apollo build 的(de)時(shí)候被壓縮。

FAQ

那麽爲(wéi / wèi)什麽提供 JSON 級别的(de)約定型配置,而(ér)非類似 webpack.config.js 的(de)編碼型配置?

首先是(shì) JSON 的(de)方式比較簡單,true/false 或是(shì)一(yī / yì /yí)些簡單的(de)字符串就(jiù)可完成配置;另外,JSON 方式能有效控制使用場景,而(ér)編程式的(de)非常不(bù)可控,roadhog 的(de)一(yī / yì /yí)個(gè)簡單改動都可能導緻之(zhī)前的(de)配置不(bù)可用。

Unexpected token 錯誤,類似下面這(zhè)樣

Error in ./index.js
Module parse failed: /Users/chencheng/Documents/Work/Misc/dva-cli/boilerplates/demo/index.js Unexpected token (15:23)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (15:23)
 @ multi index

把源碼放到(dào) src 目錄下,因爲(wéi / wèi)非 src 目錄下的(de)文件不(bù)會走 babel 編譯。

Windows/Ubuntu 下每次啓動後打開新 Tab 比較煩

# Ubuntu
$ BROWSER=none apollo-build server

# Windows
$ set BROWSER=none&&apollo-build server

多入口的(de)使用說(shuō)明

  • 多入口核心是(shì)需要(yào / yāo)在(zài) entry 裏面使用對象,指定多個(gè)入口地(dì / de)址,一(yī / yì /yí)般都需要(yào / yāo) templatePath 配合來(lái)配置, 才能自動化注入正确生成到(dào)chunk到(dào)不(bù)同的(de)入口 html。同時(shí)多入口一(yī / yì /yí)般有抽取公用 chunk的(de) 需求,這(zhè)時(shí)候可以(yǐ)結合 commonChunk 來(lái)進行公共模塊的(de)抽取
  • 注意 static 靜态資源的(de)引入相對路徑會因爲(wéi / wèi)多入口打包路徑的(de)不(bù)同而(ér)變化
  • 多入口 Demo 項目可以(yǐ)參考apollo-build-multi-entry-demo

注意

當前版本的(de) apollo build 基于(yú)webpack^4.29.6

通過webpack.config.js修改webpack配置時(shí),請按照webpack@4的(de)方式配置

在(zài)配置 extraBabelPlugins 和(hé / huò) extraBabelPresets 時(shí),使用 Babel@6 版本的(de) plugin 和(hé / huò) preset

roadhog is not defined 的(de)錯誤是(shì)配置裏面配置了(le/liǎo)dll , 但是(shì)沒有運行apollo-build buildDll

css 壓縮

目前使用OptimizeCssAssetsPlugin來(lái)壓縮css, 沒有使用css-loader和(hé / huò)post-css來(lái)壓縮

Copyright © 屯昌單支科技有限公司 2019 all right reserved,powered by Gitbook聯系方式: wanglihang@mskj.com
修訂時(shí)間: 2019-08-02 16:19:32

results matching ""

    No results matching ""