var webpack = require('webpack'); module.exports = { //插件項 plugins: [ new webpack.optimize.CommonsChunkPlugin('common.js'), new webpack.optimize.UglifyJsPlugin(), new webpack.optimize.DedupePlugin(), new webpack.optimize.OccurrenceOrderPlugin() ], //頁面入口文件配置 entry: { index : './src/js/page/index.js' }, //入口文件輸出配置 output: { path: 'dist/js/page', filename: '[name].js' }, module: { //加載器配置 loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' }, { test: /\.js$/, loader: 'jsx-loader?harmony',loader: 'babel-loader?presets[]=es2015&presets[]=react'}, { test: /\.scss$/, loader: 'style!css!sass?sourceMap'}, { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'} ] }, //其它解決方案配置 resolve: { root: 'E:/github/flux-example/src', //絕對路徑 extensions: ['', '.js', '.json', '.scss'], alias: { AppStore : 'js/stores/AppStores.js', ActionType : 'js/actions/ActionType.js', AppAction : 'js/actions/AppAction.js' } } }
⑴ plugins 是插件項,這里我們使用了一個 CommonsChunkPlugin 的插件,它用於提取多個入口文件的公共腳本部分,然后生成一個 common.js 來方便多頁面之間進行復用。
⑵ entry 是頁面入口文件配置,output 是對應輸出項配置(即入口文件最終要生成什么名字的文件、存放到哪里),其語法大致為:
{ entry: { page1: "./page1", //支持數組形式,將加載數組中的所有模塊,但以最后一個模塊作為輸出 page2: ["./entry1", "./entry2"] }, output: { path: "dist/js/page", filename: "[name].bundle.js" } }
該段代碼最終會生成一個 page1.bundle.js 和 page2.bundle.js,並存放到 ./dist/js/page 文件夾下。
⑶ module.loaders 是最關鍵的一塊配置。它告知 webpack 每一種文件都需要使用什么加載器來處理:
module: { //加載器配置 loaders: [ //.css 文件使用 style-loader 和 css-loader 來處理 { test: /\.css$/, loader: 'style-loader!css-loader' }, //.js 文件使用 jsx-loader 來編譯處理 { test: /\.js$/, loader: 'jsx-loader?harmony' }, //.scss 文件使用 style-loader、css-loader 和 sass-loader 來編譯處理 { test: /\.scss$/, loader: 'style!css!sass?sourceMap'}, //圖片文件使用 url-loader 來處理,小於8kb的直接轉為base64 { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'} ] }
如上,"-loader"其實是可以省略不寫的,多個loader之間用“!”連接起來。
注意所有的加載器都需要通過 npm 來加載,並建議查閱它們對應的 readme 來看看如何使用。
拿最后一個 url-loader 來說,它會將樣式中引用到的圖片轉為模塊來處理,使用該加載器需要先進行安裝:
npm install url-loader -save-dev
配置信息的參數“?limit=8192”表示將所有小於8kb的圖片都轉為base64形式(其實應該說超過8kb的才使用 url-loader 來映射到文件,否則轉為data url形式)。
⑷ 最后是 resolve 配置,這塊很好理解,直接寫注釋了:
resolve: { //查找module的話從這里開始查找 root: 'E:/github/flux-example/src', //絕對路徑 //自動擴展文件后綴名,意味着我們require模塊可以省略不寫后綴名 extensions: ['', '.js', '.json', '.scss'], //模塊別名定義,方便后續直接引用別名,無須多寫長長的地址 alias: { AppStore : 'js/stores/AppStores.js',//后續直接 require('AppStore') 即可 ActionType : 'js/actions/ActionType.js', AppAction : 'js/actions/AppAction.js' } }
運行webpack:
webpack 的執行也很簡單,直接執行
$ webpack --display-error-details
即可,后面的參數“--display-error-details”是推薦加上的,方便出錯時能查閱更詳盡的信息(比如 webpack 尋找模塊的過程),從而更好定位到問題。
其他主要的參數有:
$ webpack --config XXX.js //使用另一份配置文件(比如webpack.config2.js)來打包 $ webpack --watch //監聽變動並自動打包 $ webpack -p //壓縮混淆腳本,這個非常非常重要! $ webpack -d //生成map映射文件,告知哪些模塊被最終打包到哪里了
其中的 -p 是很重要的參數,曾經一個未壓縮的 700kb 的文件,壓縮后直接降到 180kb(主要是樣式這塊一句就獨占一行腳本,導致未壓縮腳本變得很大)。
在 AMD/CMD 中,我們需要對不符合規范的模塊(比如一些直接返回全局變量的插件)進行 shim 處理,這時候我們需要使用 exports-loader 來幫忙:
{ test: require.resolve("./src/js/tool/swipe.js"), loader: "exports?swipe"}
獨立打包樣式文件
有時候可能希望項目的樣式能不要被打包到腳本中,而是獨立出來作為.css,然后在頁面中以<link>標簽引入。這時候我們需要 extract-text-webpack-plugin 來幫忙:
var webpack = require('webpack'); var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { plugins: [commonsPlugin, new ExtractTextPlugin("[name].css")], entry: { //...省略其它配置
webpack打包參數:
webpack hello.js hello.bundle.js --module-bind 'css=style-loader!css-loader' --watch --progress --dislay-modules --display-reason
webpack --config webpack.dev.config.js --progress --display-modules --colors --display-reasons
