Webpack工程化解決方案easywebpack

1.概要

隨著越來越多的項目采用 Vue, React, Weex 進行業(yè)務(wù)開發(fā), 在前端構(gòu)建方面大多數(shù)是用webpack進行構(gòu)建。但存在以下問題:

各個項目都是自己從零編寫 Webpack 配置,存在很多定制性的配置,無法復(fù)用,大多都是復(fù)制拷貝。
Webpack 配置項多,繁雜,社區(qū)插件有非常多,往往不知道哪個到底可以用,存在什么問題,需要各自摸索。當需要滿足開發(fā)環(huán)境,正式環(huán)境,js/css/image壓縮,css extract, css module, sass, less, stylus, postcss, babel, cdn,單頁面,多頁面,熱更新, 前端渲染,服務(wù)器渲染等特性時,配置非常復(fù)雜。在這種情況下,急需一套穩(wěn)定的 Webpack 配置骨架,簡化項目使用難度和維護成本。

最近半年來,基于 Webpack(Vue,Weex) 經(jīng)過實際項目的不斷迭代和大家的建議,在前端渲染,單頁面渲染,服務(wù)端渲染等方面都進行過實際項目的實踐,在此基礎(chǔ)上面沉淀出一套建基于 Webpack 通用基礎(chǔ)配置且可擴展性強的前端工程化解決方案 easywebpack。

2.easywebpack功能介紹

easywebpack 是在 Webpack 上擴展出來的前端項目構(gòu)建工程化解決方案, 同時支持 Vue,React 服務(wù)端端渲染構(gòu)建,也支持 Weex Nativ 和 Web 構(gòu)建. 同時內(nèi)置 Webpack 常用功能和基礎(chǔ)插件,支持插件動態(tài)安裝,功能開啟,框架擴展等特性。

目前 easywebpack 已支持 Webpack3(easywebpack 3.x.x) 和 Webpack2(easywebpack 1.x.x),很多新特性可以馬上嘗鮮了。另外支持 Mac 和 Window 系統(tǒng)(被 Windows 坑了好久,如果可以,盡可能用 Mac)。

  • 首先我們看看 easywebpack 具備的基礎(chǔ)功能:
easywebpack.png
  • 基于 easywebpack 實現(xiàn)的解決方案
webpack-project.png

2.1 基礎(chǔ)功能

  • 支持服務(wù)端渲染, 前端渲染, 靜態(tài)頁面渲染三種構(gòu)建方式
  • 支持單頁面, 多頁面服務(wù)端渲染構(gòu)建模式
  • 默認支持 dev,test, prod 環(huán)境配置
  • 集成 webpack-hot-middleware 熱更新實現(xiàn)
  • 支持 entry 原生配置和目錄遍歷自動構(gòu)造 entry 功能
  • 支持自動根據(jù)后綴名構(gòu)建 entry 文件,比如 .vue.jsx 文件為入口文件
  • 支持 es6 class 繼承方式編寫 Webpack 配置
  • 支持 js/css/image 壓縮, 內(nèi)置支持 CDN 特性
  • 支持 css/sass/less/stylus, 支持css module 和 css extract 特性
  • 支持 loader 是否啟用,合并,覆蓋配置
  • 支持 plugin 是否啟用,合并,覆蓋配置
  • 支持 loader 和 plugin npm module 是否啟用,按需安裝
  • 支持 eslint, postcss 等特性
  • 提供 easywebpack-cli 和 webpack-tool 輔助工具。

2.2 內(nèi)置loader

  • babel-loader
  • eslint-loader
  • style-loader
  • css-loader
  • postcss-loader
  • sass-loader
  • less-loader
  • stylus-loader
  • url-loader

2.3 內(nèi)置plugin

  • extract-text-webpack-plugin
  • npm-install-webpack-plugin
  • webpack.optimize.ModuleConcatenationPlugin
  • webpack.NoEmitOnErrorsPlugin
  • webpack.ProvidePlugin
  • webpack.DefinePlugin
  • webpack.optimize.CommonsChunkPlugin
  • webpack.optimize.UglifyJsPlugin
  • webpack.HotModuleReplacementPlugin
  • progress-bar-webpack-plugin
  • imagemin-webpack-plugin
  • directory-named-webpack-plugin
  • webpack.NormalModuleReplacementPlugin
  • webpack.IgnorePlugin
  • html-webpack-plugin

3.已有解決方案

基于 easywebpack 基礎(chǔ)骨架,目前已擴展 Vue React Weex 三種解決方案,其中 easywebpack-vueeasywebpack-react 支持純前端構(gòu)建和Node端構(gòu)建模式,easywebpack-weex 支持 Native 和 Web 構(gòu)建模式。

如果你需要基于 easywebpack 擴展其他解決方案也很簡單, 只需要繼承 easywebpackWebpackClientBuilder(前端渲染構(gòu)建模式) 和 WebpackServerBuilder(服務(wù)端渲染構(gòu)建模式) 即可, 你只需要把框架相關(guān)的擴展進來即可。 大概實現(xiàn)如下:

4.解決方案擴展實現(xiàn)

4.1 前端渲染構(gòu)建模式

const EasyWebpack = require('easywebpack');
class WebpackClientBuilder extends EasyWebpack.WebpackClientBuilder {
constructor(config) {
super(config);
// call below api custom client builder
}
}
module.exports = WebpackClientBuilder;

4.2 服務(wù)端渲染構(gòu)建模式

const EasyWebpack = require('easywebpack');
class WebpackServerBuilder extends EasyWebpack.WebpackServerBuilder {
constructor(config) {
super(config);
// call below api custom server builder
}
}
module.exports = WebpackServerBuilder;

具體實現(xiàn)請參考 easyebpack-vue`,`easyebpack-react, easyebpack-weex

5.命令行工具

5.1 easywebpack-cli 命令行工具

  • Vue, React, Weex 骨架項目初始化工具, 支持純前端項目和Egg項目
  • 提供命令行 easywebpackeasy 命令編譯項目和啟動靜態(tài)功能
  • 依賴 webpack-tool 工具構(gòu)建

5.1.1 特性

5.1.2 安裝

$ npm i easywebpack-cli -g

5.1.3 運行

easywebapck -h

Usage: easywebpack [command] [options]
Options:

-V, --version output the version number
-f, --filename [path] webpack config file name, default webpack.config.js
-w, --watch webpack watch and hot-update
-m, --hash webpack md5 hash js/css/image
-c, --compress webpack compress js/css/image
-b, --build [option] w(watch), m(hash) , c(compress), ex: wm/wc/mc/wmc
-h, --help output usage information

Commands:

init [options] init webpack config or boilerplate for Vue/React/Weex
install npm install
print [env] [options] print webpack config, support print by env or config node key
build [env] webpack building
server [env] webpack building and start server

5.1.4. 命令介紹

1. 配置模板和Boilerplate初始化
  • easywebpack init

step one:

cli-init-step-one.png

step two:

cli-init-step-two.png
2. 編譯舉例
  • easywebpack build
  • easywebpack build -f build/webpack.config.js
  • easywebpack build -c
  • easywebpack build dev
  • easywebpack build test
  • easywebpack build prod
  • easywebpack build -b wmc

默認讀取項目根目錄下的 webpack.config.js 配置

3. 編譯和啟動服務(wù)舉例
  • easywebpack server
  • easywebpack server -f build/webpack.config.js
  • easywebpack server dev
  • easywebpack server test
  • easywebpack server prod
  • easywebpack server -b wmc

默認讀取項目根目錄下的 webpack.config.js 配置

4. 打印配置
easywebpack print -h

Usage: print [env] [options]
print webpack config, support print by env or config node key

Options:
-n, --node [key] print webpack config info by config node key, example: [module/module.rules/plugins] and so on
-h, --help output usage information

  • easywebpack print -n module
  • easywebpack print dev -n entry
  • easywebpack print test -n module.rules
  • easywebpack print prod -n module.rules[0]
  • easywebpack print -n plugins
  • easywebpack print -n plugins[0]
  • easywebpack print -n output
  • easywebpack print -n resolve

默認讀取項目根目錄下的 webpack.config.js 配置
GitHub:https://github.com/hubcarl/easywebpack-cli

5.2 webpack-tool 命令行工具

webpack-tool 是一個純粹的 Webpack 構(gòu)建工具, 不依賴任何框架, 支持以下特性:

  • 提供 Webpack 配置編譯功能
  • 提供 Webpack 編譯結(jié)果文件UI視圖導(dǎo)航和訪問功能
使用
//build/index.js
const WebpackTool = require('webpack-tool');
const weexNativeConfig = require('./weex/native');
const weexWebConfig = require('./weex/web');
const NODE_ENV = process.env.VIEW;
const webpackConfig = [weexNativeConfig, weexWebConfig];
const webpackTool = new WebpackTool();
if (NODE_ENV === 'development') {
  // start webpack build and show build result ui view
  webpackTool.server(webpackConfig);
} else {
  webpackTool.build(webpackConfig);
}
build-navigation.png

6.項目構(gòu)建方案配置案例

6.1 純前端項目配置和構(gòu)建

假如要實現(xiàn)基于 Vue 或者 React 實現(xiàn)一個純前端渲染項目改如何配置 webpack.config.js.

6.1.1 項目結(jié)果要求如下:

project.png
  • 支持單頁面和多頁面entry配置
  • 支持根據(jù) .vue 或者 .react 構(gòu)建入口文件
  • 支持根據(jù)目錄遍歷, 項目page根目錄為 page
  • 支持熱更新,支持css extract, 支持 css和sass(默認支持),支持構(gòu)建預(yù)覽
  • 支持cdn配置,支持構(gòu)建完成回調(diào)用于編寫自定義邏輯
  • 支持公共文件抽取,抽取文件默認為 vendor.js
  • 支持 es6 編寫
  • 支持js/css/image壓縮和hash
  • 支持eslint,babel, postcss
  • 支持dev(不壓縮,無hash,支持熱更新)和 prod(壓縮hash,css exteract) 配置

6.1.2 基于 easywebpack-vueeasywebpack-cli

上面的要求 easywebpack-vue 都支持,其中 支持eslint,babel, postcss 和 autoprefixer是默認開啟

  • 按照上面的截圖新建好項目,或者可以通過 easywebpack-ci 工具初始化完成

  • 項目安裝 easywebpack-vue 解決方案依賴

    npm install easywebpack-vue --save-dev
    
  • 編寫 ${project}/webpack.config.js配置

const BUILD_ENV = process.env.BUILD_ENV;
const cdn = BUILD_ENV === 'prod' ? { url: 'http://your.cdn.com'} : '',
module.exports = {
  type: 'client, // 指定只構(gòu)建前端渲染
  framework: 'vue', // 支持 react/weex
  entry: {
    include: 'page',
    exclude: ['page/test'],
    template: 'view/layout.html'
  }
  loader: {
    client: 'framework/vue/entry/client-loader.js'
  }
  alias: {
    asset: 'asset',
    component: 'component',
    framework: 'framework',
    store: 'store'
  },
  cdn,
  done(){ // 編譯完成
  // 這里可以做你想做的事情喲,比如 打包上傳 CDN
    if(cdn && cdn.url){
    }
  }
}

只需要配上面這么多, 就可以 Running 了,因為 easywebpack-vue 把 babel,postcss,sass都默認支持了,當然你可以擴展。

  • 命令行編譯

首先請安裝 easywebpack-ci 工具, 然后就可以用 easywebpackeasy 命令
npm install easywebpack-ci -g

  • 命令行啟動運行
easywebpack server 或 easywebpack server dev
easywebpack server prod
  • 命令行編譯,默認開發(fā)模式
easywebpack build 或 easywebpack build dev
easywebpack build prod
  • 獲取 Webpack 配置結(jié)果
const EasyWebpack = require('easywebpack-vue');
const webpackConfigList = EasyWebpack.getWebpackConfig()

6.1.3 基于 easywebpack-reacteasywebpack-cli

如果要用react實現(xiàn)類似功能, 請把上面 framework 改為 react

6.2 Vue/React Server Side Render 配置

如果要基于上面的要求實現(xiàn)一個 Vue /React 服務(wù)端渲染的構(gòu)建配置, 該如何配置,非常簡單。

6.2.1 構(gòu)建配置

  • copy 一份上面的配置
  • 去掉 type:client 配置
  • 如果 react,framework配置改為 'framework: react', 另外安裝 easywebpack-react 依賴
  • 添加 server loader template, 請查看配置舉例。
loader: {
  client: 'framework/vue/entry/client-loader.js',
  server: 'framework/vue/entry/server-loader.js'
}

完整結(jié)構(gòu)如下:

const BUILD_ENV = process.env.BUILD_ENV;
const cdn = BUILD_ENV === 'prod' ? { url: 'http://your.cdn.com'} : '',
module.exports = {
  framework: 'vue', // 支持 react/weex
  entry: {
    include: 'page',
    exclude: ['page/test'],
    template: 'view/layout.html'
  }
  loader: {
   client: 'framework/vue/entry/client-loader.js',
   server: 'framework/vue/entry/server-loader.js'
  }
  alias: {
    asset: 'asset',
    component: 'component',
    framework: 'framework',
    store: 'store'
  },
  cdn,
  done(){ // 編譯完成
    // 這里可以做你想做的事情喲,比如 打包上傳 CDN
    if(cdn && cdn.url){
    }
  }
}

6.2.2 結(jié)合 Vue vue-server-renderer 做服務(wù)端渲染, 核心代碼如下:

const renderer = require('vue-server-renderer');
// filepath 為 Webpack 構(gòu)建的服務(wù)端代碼
const bundleRenderer = renderer.createBundleRenderer(filepath, renderOptions);
// data 為 Node端獲取到的數(shù)據(jù)
const context = { state: data };
return new Promise((resolve, reject) => {
  bundleRenderer.renderToString(context, (err, html) => {
  if (err) {
    reject(err);
  } else {
    resolve(html);
  }
});

請參考 egg-view-vue 和 egg-view-vue-ssr 實現(xiàn): egg-view-vueegg-view-vue-ssr

拿到服務(wù)端渲染的 html 后,可以根據(jù) manifest 資源依賴注入 css,js 等依賴,實際項目這里要考慮緩存。完整的基于 koa, express 項目請參考下面要介紹的 Egg + Vue 服務(wù)端渲染實現(xiàn)。

6.2.3 結(jié)合 React react-dom/server 做服務(wù)端渲染, 核心代碼如下:

const React = require('react');
const ReactDOMServer = require('react-dom/server');

請參考 egg-view-react 和 egg-view-react-ssr 實現(xiàn): egg-view-reactegg-view-react-ssr

拿到服務(wù)端渲染的 html 后,可以根據(jù) manifest 資源依賴注入 css,js 等依賴,實際項目這里要考慮緩存。完整的基于 koa, express 項目請參考下面要介紹的 Egg + React 服務(wù)端渲染實現(xiàn)。

6.3 Egg + Vue 服務(wù)端渲染(Server Side Render)配置

如果要基于上面的要求實現(xiàn)一個 Egg + Vue 服務(wù)端渲染的構(gòu)建配置, 我們服務(wù)端渲染的配置基礎(chǔ)上面增加 egg: true 配置即可。

6.3.1 完整配置結(jié)構(gòu)如下:

const BUILD_ENV = process.env.BUILD_ENV;
const cdn = BUILD_ENV === 'prod' ? { url: 'http://your.cdn.com'} : '',

module.exports = {
  egg: true,
  framework: 'vue', // 支持 react/weex
  entry: {
    include: 'page',
    exclude: ['page/test'],
    template: 'view/layout.html'
  }
  loader: {
    client: 'framework/vue/entry/client-loader.js',
    server: 'framework/vue/entry/server-loader.js'
  }
  alias: {
    asset: 'asset',
    component: 'component',
    framework: 'framework',
    store: 'store'
  },
  cdn,
  done(){ // 編譯完成
    // 這里可以做你想做的事情喲,比如 打包上傳 CDN
    if(cdn && cdn.url){
    }
  }
}

6.3.2 安裝相關(guān)配置插件

項目骨架: egg-vue-webpack-boilerplate

6.4 Egg + React 服務(wù)端渲染(Server Side Render)配置

如果要基于上面的要求實現(xiàn)一個 Egg + React 服務(wù)端渲染的構(gòu)建配置,我們服務(wù)端渲染的配置基礎(chǔ)上面增加 egg: true即可。

完整結(jié)構(gòu)如下:

const BUILD_ENV = process.env.BUILD_ENV;
const cdn = BUILD_ENV === 'prod' ? { url: 'http://your.cdn.com'} : '',
module.exports = {
  egg: true,
  framework: 'react', // 支持 react/weex
  entry: {
  include: 'page',
  exclude: ['page/test'],
  template: 'view/layout.html',
  loader: {
    client: 'framework/vue/entry/client-loader.js',
    server: 'framework/vue/entry/server-loader.js'
  },
  alias: {
    asset: 'asset',
    component: 'component',
    framework: 'framework',
    store: 'store'
  },
  cdn,
  done(){ // 編譯完成
    // 這里可以做你想做的事情喲,比如 打包上傳 CDN
    if(cdn && cdn.url){
    }
  }
}

骨架項目請見: egg-react-webpack-boilerplate

6.5 Weex Native 和 Web 雙端模式構(gòu)建

假如要實現(xiàn)基于 Weex + Vue 構(gòu)建配置項目該如何配置 webpack.config.js. 除了上面的要求外,還需要支持 Native 和 Web 構(gòu)建。 基于 easywbpack-weex 配置也非常簡單, 只需要 把 framework 配置為 weex 即可。

  • 首先安裝 easywbpack-weex
npm i easywbpack-weex --save-dev
  • webpack.config.js 配置如下:
module.exports = {
  egg: true,
  framework: 'weex',
  entry: {
    include: 'page',
    exclude: ['page/test'],
    template: 'view/layout.html'
  } 
  alias: {
    asset: 'asset',
    component: 'component',
    framework: 'framework',
    store: 'store'
  },
  done(){ // 編譯完成
   // 這里可以做你想做的事情喲
  }
}
  • 獲取 Webpack Config 配置
const EasyWebpack = require('easywebpack-weex');
const webpackConfigList = EasyWebpack.getWebpackConfig()
  • 開發(fā)運行
easy server dev
easy server test
easy server prod
  • 編譯
easy build dev
easy build test
easy build prod

骨架項目請見: easywebpack-weex-boilerplate

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 在實現(xiàn) egg + vue 服務(wù)端渲染工程化實現(xiàn)之前,我們先來看看前面兩篇關(guān)于Webpack構(gòu)建和Egg的文章: ...
    hubcarl閱讀 6,051評論 0 19
  • GitChat技術(shù)雜談 前言 本文較長,為了節(jié)省你的閱讀時間,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,715評論 7 110
  • 1、引用類型有哪些?非引用類型有哪些 基本類型值(數(shù)值、布爾值、null和undefined):指的是保存在棧內(nèi)存...
    大胡子歌歌閱讀 438評論 0 0
  • 第三方推送實現(xiàn)原理:http://zhang.hu/mobile-push/ 第三方推送未來無法生存:http:/...
    crescent_star閱讀 644評論 0 51
  • 10:00觀察:早上起來,看了會兒書,發(fā)現(xiàn)自己的專注度只有二十分鐘。給高靜電話,她有句話我聽進去了‘給別人沒有價值...
    徐麗紅閱讀 87評論 0 0