Webpack 是德國開發者 Tobias Koppers 開發的一個強力的模塊打包器。 所謂包(bundle)就是一個 JavaScript 文件,它把一堆資源(assets)合併在一塊兒,以便它們能夠在同一個文件請求中發回給客戶端。 包中能夠包含 JavaScript、CSS 樣式、HTML 以及不少其它類型的文件。javascript
可以實現多種不一樣的前端模塊系統
前端頁面愈來愈複雜、代碼量變大,咱們須要使用一些模塊系統來組織代碼、把代碼分割成不一樣的模塊來使用。
目前前端模塊系統主要分爲如下幾個標準:css
以上方式有各自的優缺點,這裏不作贅述。
webpack 做爲一個智能解析器,能夠處理幾乎任何第三方的庫,不管他們的模塊形式是 commonjs,amd 仍是普通的 js 文件,甚至加載依賴的時候能夠動態表達式:html
import React, { PropTypes } from
'react'
require(
'es6-promise'
).polyfill()
require(
"./templates/"
+ name +
".jade"
)
var
$ = require(
'jQuery'
)
|
分塊打包
資源請求是個老生常談的優化問題,有兩個極端的方向來處理資源:前端
webpack 打包前端資源(模塊)時可以實現代碼分割,按需加載,如在單頁面應用裏,將每一個 page 的資源單獨打包,按頁面加載。這種方式被稱爲 code splitting(具體實現方式查看:https://webpack.github.io/docs/code-splitting.html。java
處理全部資源
目前模塊系統只能處理 javascript,而咱們還有不少其餘靜態資源須要處理,好比:node
配置 webpack 後,這些都很容易處理。react
gulp、grunt 是自動化任務構建工具。
webpack 是模塊化解決方案。jquery
gulp 是經過一系列插件將本來複雜繁瑣的任務(Task)自動化,並不能將你的 css 等非 js 資源模塊化,它與 webpack 之間有必定的功能重合,好比打包、壓縮混淆、圖片轉 base64 等等。但它們的目的跟要解決的問題是不同的。webpack
webpack 本質上是相似 browserify、seajs 、requirejs 的JS模塊化的方案。其中 seajs / require 是一種類型,browserify / webpack 是另外一種類型。git
seajs / require : 是一種在線」編譯」 模塊的方案,至關於在頁面上加載一個 CMD/AMD 解釋器。這樣瀏覽器就認識了 define、exports、module 這些東西。也就實現了模塊化。
browserify / webpack : 是一種預編譯模塊的方案,相比於上面 ,這個方案更加智能。這裏以webpack爲例。首先,它是預編譯的,不須要在瀏覽器中加載解釋器。另外,你在本地直接寫JS,無論是 AMD / CMD / ES6 風格的模塊化,它都能認識,而且編譯成瀏覽器認識的JS。
首先看一個簡單的 webpack 配置圖。
webpack.config.js:
Webpack的配置主要爲了這幾個項目:
devtool
devtool 屬性能夠配置調試代碼的方式,有多種調試方式。devtool 通常只在開發時使用,生產環境下應將值設爲 false。經常使用的值爲如下兩個:
其餘還有eval-source-map、cheap-source-map、cheap-module-source-map、cheap-module-eval-source-map、hidden-source-map,也能夠本身組合,如cheap-module-eval-source-map。
// webpack.config.js
module.exports = {
devtool:
'cheap-module-eval-source-map'
};
|
聽說cheap-module-eval-source-map絕大多數狀況下都會是最好的選擇,這也是下版本 webpack 的默認選項。
具體使用參考官網 devtool 部分
entry 和 output
entry 用來定義入口文件,能夠是個字符串或數組或者對象。
當 entry 是個字符串的時候:
module.exports = {
entry:
'./main.js'
};
|
當 entry 是個數組的時候,裏面一樣包含入口 js 文件,另一個參數能夠是用來配置 webpack 提供的一個靜態資源服務器,webpack-dev-server。webpack-dev-server 會監控項目中每個文件的變化,實時的進行構建,而且自動刷新頁面:
module.exports = {
entry: [
'webpack/hot/only-dev-server'
,
'./main.js'
]
};
|
當 entry 是個對象的時候,咱們能夠將不一樣的文件構建成不一樣的文件,按需使用:
module.exports = {
entry: {
a:
'./a.js'
,
b:
'./b.js'
}
};
|
output 用於定義構建後的文件的輸出,是個對象。其中包含path和filename:
module.exports = {
output: {
path:
'./build'
,
filename:
'bundle.js'
}
};
|
若是有多個入口文件分開打包,能夠經過[name]來命名打包的輸出文件。
module.exports = {
entry: {
a:
"./a"
,
b:
"./b"
,
c: [
"./c"
,
"./d"
]
},
output: {
path: path.join(__dirname,
"dist"
),
filename:
"[name].entry.js"
}
};
|
module
module 主要是用來配置加載器(Loaders),包括loaders、preLoaders、postLoaders、noParse。
webpack 自己只能處理 JavaScript 模塊,若是要處理其餘類型的文件,就須要使用 loader 進行轉換,本文第六章將會介紹一些經常使用的 Loaders。
loaders、preLoaders、postLoaders的配置選項包括如下幾方面:
module.exports = {
module: {
preLoaders: [
{test: /\.js$/, loader:
"eslint-loader"
, exclude: /node_modules/}
//打包前使用eslint檢測js
],
loaders: [
{test: /\.less$/, loader:
'style-loader!css-loader!less-loader'
},
//處理css文件,把less編譯成css
{test: /\.(png|jpg)$/, loader:
'url-loader?limit=8192'
}
// 處理圖片,大小低於8k的文件編譯爲base64
]
}
};
|
noParse是 webpack 的一個頗有用的配置項,若是你肯定一個模塊中沒有其它新的依賴就能夠配置這項,webpack 將再也不掃描這個文件中的依賴。
module: {
noParse: [/moment-
with
-locales/]
}
|
具體使用參考官網 module 部分
官網也收集了經常使用的 Loaders 列表:list-of-loaders
resolve
resolve 用來配置文件路徑的指向。能夠定義文件跟模塊的默認路徑及後綴等,節省 webpack 搜索文件的時間、優化引用模塊時的體驗。經常使用的包括alias、extensions、root、modulesDirectories屬性:
//webpack.config.js
...
resolve: {
alias: {
'someutil'
: path.join(__dirname,
'./src/util/someutil'
),
'react-dom'
: path.join(nodeModulesPath,
'react-dom/dist/react-dom.min'
)
}
}
...
|
//app.js
//配置resolve.alias前
import react-dom form
'react-dom'
//此時默認載入'/node_modules/react-dom/dist/react-dom.js'
import someutil form
'../../src/util/someutil'
//須要定位該文件相對位置
//配置resolve.alias後
import react-dom form
'react-dom'
//此時載入壓縮後的'react-dom.min.js'
import someutil form
'someutil'
//不須要再寫相對位置,由於已在resolve.alias中定義
|
//webpack.config.js
...
resolve: {
extensions: [
''
,
'.js'
,
'.jsx'
,
'.json'
,
'.css'
]
}
...
|
//app.js
//配置resolve.extensions前
import a form
'a.js'
import b form
'b.json'
import c form
'c.css'
//配置resolve.extensions後
import a form
'a'
import b form
'b'
import c form
'c'
|
//webpack.config.js
var
path = require(
'path'
);
resolve: {
root: [
path.resolve(
'./app/modules'
),
path.resolve(
'./vendor/modules'
)
]
}
//這樣設置後,會增長搜索app/modules和vendor/modules下全部node_modules裏面的模塊。
|
//webpack.config.js
...
resolve: {
modulesDirectories: [
'node_modules'
,
'./src/component'
]
}
...
|
//app.js
//配置resolve.modulesDirectories前
import a form
'../../src/component/a'
import b form
'../../src/component/b'
//配置resolve.modulesDirectories後
import a form
'a'
import b form
'b'
|
具體使用參考官網 resolve 部分
plugins
插件,比 loader 更強大,能使用更多 webpack 的 api。webpack 自己內置了一些經常使用的插件,還能夠經過 npm 安裝第三方插件。本文第七章將會介紹一些經常使用的插件。
var
HtmlWebpackPlugin = require(
'html-webpack-plugin'
);
module.exports = {
plugins: {
new
webpack.optimize.OccurenceOrderPlugin(),
//爲組件分配ID
new
webpack.HotModuleReplacementPlugin(),
//熱加載插件
new
webpack.optimize.UglifyJsPlugin(),
//壓縮混淆js
new
webpack.NoErrorsPlugin(),
//跳過編譯時出錯的代碼並記錄
new
ExtractTextPlugin(
'[name]-[hash:5].min.css'
)
//將css單獨打包並重命名
}
}
|
具體使用參考官網內置 plugins 列表 list-of-plugins 部分,這裏有全部內置插件的詳細使用說明。
externals
當咱們想在項目中require一些其餘的類庫或者API,而又不想讓這些類庫的源碼被構建到運行時文件中。例如 React、jQuery 等文件咱們想使用 CDN 的引用,不想把他們打包進輸出文件。就能夠經過配置 externals 參數來配置:
module.exports = {
externals: {
jQuery:
true
}
};
|
而後在頁面裏引入< script src="//cdn/jquery.min.js">
這樣 jQuery 就不用打包了,直接指向 windows.jQuery 就好
externals 部分
其餘
除以上 6 個經常使用配置屬性外,webpack 的配置屬性還有context
、cache
、 profile
等等,我的以爲並不經常使用,各位能夠前往官網 configuration 詳細查看。
babel-loader
babel-loader 用來編譯下一代 JavaScript,好比 ES六、React 等,編譯 ES六、React 的話還須要安裝 babel-preset-es201五、babel-preset-react。
eslint-loader
配合 eslint 用來規範糾錯 js,你可能同時還會須要 babel-eslint、eslint-plugin-react。
style-loader、css-loader、less-loader、sass-loader
處理 css、less、sass 文件
postcss-loader
用 postcss 來處理 CSS,最被經常使用的是其 autoprefixer 插件
resolve-url-loader
用來解析 css 裏的 url() 聲明裏的文件的相對路徑,使用 css-loader 時通常也必需要同時使用 resolve-url-loader
file-loader
用來處理文件名及路徑,好比給文件添加 hash,返回文件相對路徑等。
url-loader
與上面的 file-loader 相似,可是當文件小於設定的 limit 時能夠處理成 Data Url(base 64)。
raw-loader
把文件內容做爲字符串返回。例如var fileContent = require(‘raw!./file.txt’),這裏把./file.txt的內容做爲字符串返回。
imports-loader
用於向一個模塊的做用域內注入變量。
舉個栗子,好比咱們須要使用bootstrap.js,這個文件雖然依賴jQuery但其內部沒有require(‘jquery’),這致使文件內的jQuery對象不可識別,因此模塊化調用bootstrap.js時就會報錯jQuery is not defined`。使用 imports-loader 的話:
require(
'imports?jQuery=jquery!bootstrap/dist/js/bootstrap'
);
|
imports-loader 會在 bootstrap 的源碼前面,注入以下代碼:
/* IMPORTS FROM imports-loader */
var
jQuery = require(
"jquery"
);
|
exports-loader
用於向一個模塊中提供導出模塊功能。功能與imports-loader相似,但他是在文件的最後添加一行。
舉個栗子,好比file.js中沒有調用export導出模塊,或者沒有define定義模塊,所以沒法模塊化調用它。可使用 exports-loader:
require(
"exports?file,parse=helpers.parse!./file.js"
);
|
他會在./file.js文件的最後添加以下代碼:
/* EXPORTS FROM exports-loader */
exports[
"file"
] = (file);
exports[
"parse"
] = (helpers.parse);
|
expose-loader
這個 loader 是將某個對象暴露成一個全局變量。
舉個栗子,好比把jQuery對象暴露成全局變量。這樣,那些bootstrap.js之類的文件就都能訪問這個變量了。
module: {
loaders: [
{ test: require.resolve(
"jquery"
), loader:
"expose?$!expose?jQuery"
},
]
}
|
react-hot-loader
React 的網頁熱加載刷新 loader。同時須要配合使用 webpack-dev-server 。
具體的使用方法請在官網list-of-plugins查詢,本文只簡單介紹幾個經常使用插件。
CommonsChunkPlugin
插件用法比較多,經常使用的是把一些不常常更改的公共組件合併壓縮成一個 common 文件。有些類庫如utils, bootstrap之類的可能被多個頁面共享,最好是能夠合併成一個js,而非每一個js單獨去引用。這樣可以節省一些空間。
彷佛只有在多入口文件時才能把公共文件提取出來,但通常模塊化都建議單入口文件,因此我的以爲這個插件對我並無什麼卵用,有多入口需求的同窗可使用。
extract-text-webpack-plugin
第三方插件,將 CSS 打包成獨立文件,而非內聯。
HotModuleReplacementPlugin
代碼熱替換。
HtmlWebpackPlugin
生成 HTML 文件,配合 ExtractTextPlugin 能夠加入打包後的 js 和 css。
NoErrorsPlugin
報錯但不退出 webpack 進程。
OccurenceOrderPlugin
經過計算模塊出現次數來分配模塊。經過這個插件webpack能夠分析和優先考慮使用最多的模塊,併爲它們分配最小的ID。這個常常被使用能夠較快地得到模塊。這使得模塊能夠預讀,建議這樣能夠減小總文件大小。
ProvidePlugin
定義一個共用的插件入口。
new
webpack.ProvidePlugin({
$:
"jquery"
,
jQuery:
"jquery"
})
|
這樣就可直接在文件中使用$,無需再require(‘jQuery’)。
UglifyJsPlugin
js 代碼壓縮混淆 。
DedupePlugin
檢測徹底相同(以及幾乎徹底相同)的文件,並把它們從輸出中移除。
DefinePlugin
主要用來定義全局的環境變量,以便咱們在本身的程序中引用它。
webpack-visualizer-plugin
一個第三方插件,能夠生成一個文件查看項目引用的全部模塊的佔比。
區分開發及生產環境
前端開發環境一般分爲兩種:
爲了區分咱們能夠建立兩個文件分別進行不一樣環境下的配置:
同時 webpack 還提供了 DefinePlugin 插件來設置全局環境變量,後面會根據設置的不一樣環境變量決定是否打包壓縮,仍是啓動dev server 或者是 prod server
plugins: [
new
webpack.DefinePlugin({
'process.env.NODE_ENV'
: JSON.stringify(
'production'
)
// or development
})
]
|
判斷當前環境是不是生產環境
var
isProduction =
function
() {
return
process.env.NODE_ENV ===
'production'
;
}
|
使用代碼熱替換
使用代碼熱替換在開發的時候無需刷新頁面便可看到更新,只在開發環境的配置文件使用,具體配置以下。
npm install --save-dev webpack-dev-server webpack-dev-middleware express
|
把webpack/hot/dev-server加入到 webpack 配置文件的 entry 項:
<!-- webpack.config.dev.js -->
entry: [
'./src/app.js'
],
|
把new webpack.HotModuleReplacementPlugin()加入到 webpack 配置文件的 plugins 項:
<!-- server.js -->
var
webpack = require(
'webpack'
);
var
WebpackDevServer = require(
'webpack-dev-server'
);
var
config = require(
'./webpack.config'
);
var
compiler = webpack(config);
var
server =
new
WebpackDevServer(compiler, {
publicPath: config.output.publicPath,
hot:
true
,
historyApiFallback:
true
,
stats: {
colors:
true
,
hash:
false
,
timings:
true
,
chunks:
false
,
chunkModules:
false
,
modules:
false
}
});
server.listen(3000,
'localhost'
,
function
(err, result) {
if
(err) {
return
console.log(err);
}
});
|
在 package.json 中定義啓動監聽熱加載:
<!-- package.json -->
"scripts"
: {
"start"
:
"node server.js"
}
|
如今你能夠經過運行npm start啓動服務器。
編譯 ES六、React
這裏主要是藉助 Babel 進行編譯。
安裝依賴:
npm install --save-dev babel-loader babel-core babel-preset-stage-0 babel-preset-es2015 babel-preset-react babel-preset-react-hmre
|
在項目根目錄新建個.babelrc文件:
<!-- .babelrc -->
{
"presets"
: [
"es2015"
,
"stage-0"
,
"react"
]
}
|
配置 webpack 配置文件的 module 項:
<!-- webpack.config.js -->
module: {
loaders: [{
test: /\.js$/,
loaders: [
'react-hot'
,
'babel'
],
//若生產環境下去掉'react-hot'
include: path.join(__dirname,
'src'
)
}}]
}
|
使用 ESLint 檢查規範 js 代碼
ESLint 是個代碼錯誤與風格檢測工具,能夠輔助編碼規範執行,有效控制代碼質量。
ESLint 主要有如下特色:
安裝依賴:
npm install --save-dev eslint eslint-loader eslint-plugin-react
|
項目根目錄新建.eslintrc文件,用來配置 ESLint 規則,如下爲常見規則:
<!-- .eslintrc -->
{
"parserOptions"
: {
//EsLint經過parserOptions,容許指定校驗的ecma的版本,及ecma的一些特性
"ecmaVersion"
: 6,
//指定ECMAScript支持的版本,6爲ES6
"sourceType"
:
"module"
,
//指定來源的類型,有兩種」script」或」module」
"ecmaFeatures"
: {
// ecmaFeatures指定你想使用哪些額外的語言特性
"jsx"
:
true
//啓動JSX
}
},
"parser"
:
"babel-eslint"
,
// EsLint默認使用esprima作腳本解析,也能夠切換成babel-eslint解析
"env"
: {
// Environment能夠預設好的其餘環境的全局變量,如brower、node環境變量、es6環境變量、mocha環境變量等
"browser"
:
true
,
"node"
:
true
,
"es6"
:
true
,
"mocha"
:
true
},
"plugins"
: [
// EsLint容許使用第三方插件
"react"
],
extends: [
// Extends是EsLint默認推薦的驗證你可使用配置選擇哪些校驗是你所須要的
"eslint:recommended"
],
rules: [
// 自定義規則
no-empty: [
"error"
, {
"allowEmptyCatch"
:
true
}],
"strict"
: [2,
"never"
],
"react/jsx-uses-react"
:
"error"
,
"react/jsx-uses-vars"
:
"error"
,
"no-console"
: [
"error"
, { allow: [
"warn"
,
"error"
,
"log"
] }]
],
"globals"
: {
// 即插件在執行過程當中用到的其它全局變量
}
}
|
在項目根目錄新建.eslintignore 文件告訴 ESLint 去忽略特定的文件和目錄:
<!-- .eslintignore -->
dist
node_modules
dependent
coverage
webpack.*.js
*Server.js
|
在Sublime中安裝插件:
SublimeLinter
SublimeLinter-contrib-eslint
更多請訪問 eslint、babel-eslint、eslint-plugin-reac、eslint-loader、ESLint 使用入門、Lint Like It’s 2015
壓縮代碼
使用 webpack 內置的 UglifyJsPlugin 便可:
<!-- webpack.config.js -->
plugins: [
new
webpack.optimize.UglifyJsPlugin({
compress: {
warnings:
false
}
})
]
|
Code Spliiting,分割代碼,按需加載
對於大型的web 應用而言,把全部的代碼放到一個文件的作法效率不好,特別是在加載了一些只有在特定環境下才會使用到的阻塞的代碼的時候。Webpack有個功能會把你的代碼分離成Chunk,後者能夠按需加載。這個功能就是 Code Spliiting
Code Spliting的具體作法就是一個分離點,在分離點中依賴的模塊會被打包到一塊兒,能夠異步加載。一個分離點會產生一個打包文件。
本文這裏主要是基於 React 與 React-Router 的 Code Spliiting。開篇說了 webpack 目前已經更新到 2.x 版本, 1.x 與 2.x 的 Code Spliiting 方法略有不一樣,這裏分開來說。
webpack 1.x 的例子:
<router history=
"{history}"
>
<route path=
"/"
getcomponent=
"{(location,"
callback)=
""
> {
require.ensure([],
function
(require) {
callback(
null
, require(
'./HomePage.jsx'
));
});
}}
/>
<route path=
"/about"
getcomponent=
"{(location,"
callback)=
""
> {
require.ensure([],
function
(require) {
callback(
null
, require(
'./AboutPage.jsx'
));
});
}}
/>
</route></route></router>
|
webpack 2.x 的例子:
class Page extends React.Component {
render() {
<route path=
"{this.props.path}"
getcomponent=
"{(location,"
callback)=
""
> {
System.import(
this
.props.component)
.then((component) => {
callback(
null
, component);
});
}
}
}
</route>
|
<router history=
"{history}"
>
<page path=
"/about"
component=
"./AboutPage.jsx"
>
</page></router>
|
使用 DllPlugin 和 DllReferencePlugin 分割代碼
經過 DllPlugin 和 DllReferencePlugin,webpack 引入了另一種代碼分割的方案。咱們能夠將經常使用的庫文件打包到 dll 包中,而後在 webpack 配置中引用。業務代碼的能夠像往常同樣使用 require 引入依賴模塊,好比 require(‘react’), webpack 打包業務代碼時會首先查找該模塊是否已經包含在 dll 中了,只有 dll 中沒有該模塊時,webpack 纔將其打包到業務 chunk 中。
首先咱們使用 DllPlugin 將經常使用的庫打包在一塊兒:
var
webpack = require(
'webpack'
);
module.exports = {
entry: {
vendor: [
'lodash'
,
'react'
],
},
output: {
filename:
'[name].[chunkhash].js'
,
path:
'build/'
,
},
plugins: [
new
webpack.DllPlugin({
name:
'[name]_lib'
,
path:
'./[name]-manifest.json'
,
})]
};
|
該配置會產生兩個文件,模塊庫文件:vender.[chunkhash].js 和模塊映射文件:vender-menifest.json。其中 vender-menifest.json 標明瞭模塊路徑和模塊 ID(由 webpack 產生)的映射關係,其文件內容以下:
{
"name"
:
"vendor_lib"
,
"content"
: {
"./node_modules/.npminstall/lodash/4.17.2/lodash/lodash.js"
: 1,
"./node_modules/.npminstall/webpack/1.13.3/webpack/buildin/module.js"
: 2,
"./node_modules/.npminstall/react/15.3.2/react/react.js"
: 3,
...
}
}
|
而後在業務代碼的 webpack 配置文件中使用 DllReferencePlugin 插件引用:
var
webpack = require(
'webpack'
);
module.exports = {
entry: {
app: [
'./app'
],
},
output: {
filename:
'[name].[chunkhash].js'
,
path:
'build/'
,
},
plugins: [
new
webpack.DllReferencePlugin({
context:
'.'
,
manifest: require(
'./vendor-manifest.json'
),
})]
};
|
須要注意的是:dll包的代碼是不會執行的,須要在業務代碼中經過require顯示引入。
編譯 less/sass、自動添加瀏覽器前綴、將 css 單獨打包
我用的是 less,因此這裏以 less 爲例。
安裝編譯 less 的依賴:
$ npm install css-loader style-loader less less-loader --save-dev
|
安裝處理 css 內 url() 聲明路徑的依賴:
$ npm install resolve-url-loader --save-dev
|
安裝 autoprefixer 依賴:
$ npm install postcss-loader autoprefixer --save-dev
|
配置 webpack 配置文件的 module、postcss項:
<!-- webpack.config.js -->
module: {
loaders: [{
test: /\.less$/,
loader:
'style'
,
'css?modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]!resolve-url!postcss!less'
include: path.join(__dirname,
'src'
)
}}]
},
postcss: [
require(
'autoprefixer'
)
]
|
生產環境下咱們可能會須要把 css 單獨打包出來,這時須要用到 ExtractTextPlugin 插件 :
npm install extract-text-webpack-plugin --save-dev
|
var
ExtractTextPlugin = require(
'extract-text-webpack-plugin'
);
...
plugins: [
new
ExtractTextPlugin(
'[name]-[hash:5].min.css'
)
],
module: {
loaders: [{
test: /\.less$/,
loader: ExtractTextPlugin.extract(
'style'
,
'css?modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]!resolve-url!postcss!less'
)
include: path.join(__dirname,
'src'
)
}}]
},
postcss: [
require(
'autoprefixer'
)
]
...
|
壓縮圖片、將圖片轉爲 base64
圖片處理常見的loader有如下三種:
安裝依賴:
npm url-loader image-webpack-loader --save-dev
|
module: {
loaders: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
'url?limit=10000&name=img/[hash:8].[name].[ext]'
,
// 圖片小於8k就轉化爲 base64, 或者單獨做爲文件
'image-webpack'
// 圖片壓縮
]
}
]
}
|
給文件添加 hash 緩存、自動生成頁面
在 output 項給生成文件添加 hash:
output: {
...
filename:
'[chunkhash:8].bundle.js'
// chunkhash 默認是16位,可自定義配置
...
}
|
文件名帶上 hash 值後,這個值在每次編譯的時候都會發生變化,都須要在 html 文件裏手動修改引用的文件名,這種重複工做很瑣碎且容易出錯,這裏咱們可使用 html-webpack-plugin 來幫咱們自動處理這件事情:
// 在 app 目錄下建一個 index.tpl.html 做爲鉤子
<meta charset=
"UTF-8"
>
<div id=
"root"
></div>
|
// 在 webpack.config.dev.js 和 webpack.config.prod.js 添加配置代碼,便可生成相對應的 index.html
plugins: [
new
HtmlWebpackPlugin({
template:
'app/index.tpl.html'
,
minify: {
removeComments:
true
,
collapseWhitespace:
true
,
removeRedundantAttributes:
true
,
useShortDoctype:
true
,
removeEmptyAttributes:
true
,
removeStyleLinkTypeAttributes:
true
,
keepClosingSlash:
true
,
minifyJS:
true
,
minifyCSS:
true
,
minifyURLs:
true
,
},
inject:
'body'
,
filename:
'index.html'
})
]
|
使用 Fetch
我我的的項目裏 Fetch 已經徹底替代 Ajax 了,使用 Fetch 爲了兼容舊瀏覽器須要使用一些膩子腳本,咱們能夠將膩子腳本暴露到全局。這裏主要使用前文中提到的import-loader、exports-loader。
安裝依賴:
npm install imports-loader exports-loader --save-dev
npm install es6-promise whatwg-fetch --save
|
配置 webpack 配置文件的 plugins 項:
plugins: [
new
webpack.ProvidePlugin({
'Promise'
:
'es6-promise'
,
'fetch'
:
'imports?this=>global!exports?global.fetch!whatwg-fetch'
}),
],
|
這樣就能夠直接在開發文件中使用 Fetch。
再次說明下本文的 配套 DEMO 請訪問 https://github.com/tumars/boilerplate-webpack-react-es6-cssModule 查看。
本文還會繼續更新修改,歡迎各位交流指教
。