安裝
css
//全局安裝 npm install -g webpack //安裝到你的項目目錄 npm install --save-dev webpack
在終端中使用npm init
命令能夠自動建立這個package.json文件html
npm init
package.json文件已經就緒,咱們在本項目中安裝Webpack做爲依賴包node
// 安裝Webpack
npm install --save-dev webpack
module.exports = { entry: __dirname + "index.js",//已屢次說起的惟一入口文件 output: { path: __dirname + "/dist",//打包後的文件存放的地方 filename: "bundle.js"//打包後輸出文件的文件名 } }
在package.json中對npm的腳本部分進行相關設置便可,設置方法以下。react
{ "name": "webpack-sample-project", "version": "1.0.0", "description": "", "scripts": { "start": "webpack" //配置的地方就是這裏啦,至關於把npm的start命令指向webpack命令 }, "author": "", "license": "ISC", "devDependencies": { "webpack": "^1.12.9" } }
npm的start
是一個特殊的腳本名稱,它的特殊性表如今,在命令行中使用npm start
就能夠執行相關命令,若是對應的此腳本名稱不是start
,想要在命令行中運行時,須要這樣用npm run {script name}
如npm run build
jquery
devtool選項 | 配置結果 |
source-map | 在一個單獨的文件中產生一個完整且功能徹底的文件。這個文件具備最好的source map,可是它會減慢打包文件的構建速度; |
cheap-module-source-map | 在一個單獨的文件中生成一個不帶列映射的map,不帶列映射提升項目構建速度,可是也使得瀏覽器開發者工具只能對應到具體的行,不能對應到具體的列(符號),會對調試形成不便; |
eval-source-map | 使用eval打包源文件模塊,在同一個文件中生成乾淨的完整的source map。這個選項能夠在不影響構建速度的前提下生成完整的sourcemap,可是對打包後輸出的JS文件的執行具備性能和安全的隱患。不過在開發階段這是一個很是好的選項,可是在生產階段必定不要用這個選項; |
cheap-module-eval-source-map | 這是在打包文件時最快的生成source map的方法,生成的Source Map 會和打包後的JavaScript文件同行顯示,沒有列映射,和eval-source-map 選項具備類似的缺點; |
eval-source-map
是一個很好的選項,不過記得只在開發階段使用它,繼續上面的例子,進行以下配置webpack
module.exports = { devtool: 'eval-source-map',//配置生成Source Maps,選擇合適的選項 entry: __dirname + "/app/main.js", output: { path: __dirname + "/public", filename: "bundle.js" } }
npm install --save-dev webpack-dev-server
devserver做爲webpack配置選項中的一項,具備如下配置選項web
devserver配置選項 | 功能描述 |
contentBase | 默認webpack-dev-server會爲根文件夾提供本地服務器,若是想爲另一個目錄下的文件提供本地服務器,應該在這裏設置其所在目錄(本例設置到「public"目錄) |
port | 設置默認監聽端口,若是省略,默認爲」8080「 |
inline | 設置爲true ,當源文件改變時會自動刷新頁面 |
colors | 設置爲true ,使終端輸出的文件爲彩色的 |
historyApiFallback | 在開發單頁應用時很是有用,它依賴於HTML5 history API,若是設置爲true ,全部的跳轉將指向index.html |
繼續把這些命令加到webpack的配置文件中正則表達式
module.exports = { devtool: 'eval-source-map', entry: __dirname + "/app/main.js", output: { path: __dirname + "/public", filename: "bundle.js" }, devServer: { contentBase: "./public",//本地服務器所加載的頁面所在的目錄 colors: true,//終端中輸出結果爲彩色 historyApiFallback: true,//不跳轉 inline: true//實時刷新 } }
經過使用不一樣的loader,webpack經過調用外部的腳本或工具能夠對各類各樣的格式的文件進行處理,好比說分析JSON文件並把它轉換爲JavaScript文件,或者說把下一代的JS文件(ES6,ES7)轉換爲現代瀏覽器能夠識別的JS文件。npm
Loaders須要單獨安裝而且須要在webpack.config.js下的modules
關鍵字下進行配置,Loaders的配置選項包括如下幾方面:json
test
:一個匹配loaders所處理的文件的拓展名的正則表達式(必須)loader
:loader的名稱(必須)include/exclude
:手動添加必須處理的文件(文件夾)或屏蔽不須要處理的文件(文件夾)(可選);query
:爲loaders提供額外的設置選項(可選)//安裝能夠裝換JSON的loader
npm install --save-dev json-loader
module.exports = { devtool: 'eval-source-map', entry: __dirname + "/app/main.js", output: { path: __dirname + "/public", filename: "bundle.js" }, module: {//在配置文件裏添加JSON loader loaders: [ { test: /\.json$/, loader: "json" } ] }, devServer: { contentBase: "./public", colors: true, historyApiFallback: true, inline: true } }
Babel實際上是幾個模塊化的包,其核心功能位於稱爲babel-core
的npm包中,不過webpack把它們整合在一塊兒使用,可是對於每個你須要的功能或拓展,你都須要安裝單獨的包(用得最多的是解析Es6的babel-preset-es2015包和解析JSX的babel-preset-react包)。
// npm一次性安裝多個依賴模塊,模塊之間用空格隔開
npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
module.exports = { devtool: 'eval-source-map', entry: __dirname + "/app/main.js", output: { path: __dirname + "/public", filename: "bundle.js" }, module: { loaders: [ { test: /\.json$/, loader: "json" }, { test: /\.js$/, exclude: /node_modules/, loader: 'babel',//在webpack的module部分的loaders裏進行配置便可 query: { presets: ['es2015','react'] } } ] }, devServer: { contentBase: "./public", colors: true, historyApiFallback: true, inline: true } }
".babelrc" 的配置文件,webpack會自動調用.babelrc
裏的babel配置選項
//.babelrc { "presets": ["react", "es2015"] }
webpack提供兩個工具處理樣式表,css-loader
和 style-loader
,兩者處理的任務不一樣,css-loader
使你可以使用相似@import
和 url(...)
的方法實現 require()
的功能,style-loader
將全部的計算後的樣式加入頁面中,兩者組合在一塊兒使你可以把樣式表嵌入webpack打包後的JS文件中。
//安裝
npm install --save-dev style-loader css-loader
//使用 module.exports = { devtool: 'eval-source-map', entry: __dirname + "/app/main.js", output: { path: __dirname + "/build", filename: "bundle.js" }, module: { loaders: [ { test: /\.json$/, loader: "json" }, { test: /\.js$/, exclude: /node_modules/, loader: 'babel' }, { test: /\.css$/, loader: 'style!css'//添加對樣式表的處理 } ] }, devServer: {...} }
注:感嘆號的做用在於使同一文件可以使用不一樣類型的loader
module.exports = { devtool: 'eval-source-map', entry: __dirname + "/app/main.js", output: {...}, module: { loaders: [ { test: /\.json$/, loader: "json" }, { test: /\.js$/, exclude: /node_modules/, loader: 'babel' }, { test: /\.css$/, loader: 'style!css?modules'//跟前面相比就在後面加上了?modules } ] }, devServer: {...} }
首先安裝postcss-loader 和 autoprefixer(自動添加前綴的插件)
npm install --save-dev postcss-loader autoprefixer
//webpack配置文件 module.exports = { devtool: 'eval-source-map', entry: __dirname + "/app/main.js", output: {...}, module: { loaders: [ { test: /\.json$/, loader: "json" }, { test: /\.js$/, exclude: /node_modules/, loader: 'babel' }, { test: /\.css$/, loader: 'style!css?modules!postcss' } ] }, postcss: [ require('autoprefixer')//調用autoprefixer插件 ], devServer: {...} }
要使用某個插件,咱們須要經過npm安裝它,而後要作的就是在webpack配置中的plugins關鍵字部分添加該插件的一個實例(plugins是一個數組)繼續看例子,咱們添加了一個實現版權聲明的插件。
//webpack.config.js var webpack = require('webpack'); module.exports = { devtool: 'eval-source-map', entry: __dirname + "/app/main.js", output: {...}, module: { loaders: [ { test: /\.json$/, loader: "json" }, { test: /\.js$/, exclude: /node_modules/, loader: 'babel' }, { test: /\.css$/, loader: 'style!css?modules!postcss' }//這裏添加PostCSS ] }, postcss: [ require('autoprefixer') ], plugins: [ new webpack.BannerPlugin("Copyright Flying Unicorns inc.")//在這個數組中new一個就能夠了 ], devServer: {...} }
這個插件的做用是依據一個簡單的模板,幫你生成最終的Html5文件,這個文件中自動引用了你打包後的JS文件。每次編譯都在文件名中插入一個不一樣的哈希值。
npm install --save-dev html-webpack-plugin
Hot Module Replacement(HMR)也是webpack裏頗有用的一個插件,它容許你在修改組件代碼後,自動刷新實時預覽修改後的效果。
//webpack中的配置 var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { devtool: 'eval-source-map', entry: __dirname + "/app/main.js", output: { path: __dirname + "/build", filename: "bundle.js" }, module: { loaders: [ { test: /\.json$/, loader: "json" }, { test: /\.js$/, exclude: /node_modules/, loader: 'babel' }, { test: /\.css$/, loader: 'style!css?modules!postcss' } ] }, postcss: [ require('autoprefixer') ], plugins: [ new HtmlWebpackPlugin({ template: __dirname + "/app/index.tmpl.html" }), new webpack.HotModuleReplacementPlugin()//熱加載插件 ], devServer: { colors: true, historyApiFallback: true, inline: true, hot: true } }
安裝react-transform-hmr
npm install --save-dev babel-plugin-react-transform react-transform-hmr
配置Babel
{ "presets": ["react", "es2015"], "env": { "development": { "plugins": [["react-transform", { "transforms": [{ "transform": "react-transform-hmr", "imports": ["react"], "locals": ["module"] }] }]] } } }
目前爲止,咱們已經使用webpack構建了一個完整的開發環境。可是在產品階段,可能還須要對打包的文件進行額外的處理,好比說優化,壓縮,緩存以及分離CSS和JS。
對於複雜的項目來講,須要複雜的配置,這時候分解配置文件爲多個小的文件可使得事情層次分明,以上面的例子來講,咱們建立一個「webpack.production.config.js」的文件,在裏面加上基本的配置,它和原始的webpack.config.js很像,以下
咱們繼續用例子來看看如何添加它們,OccurenceOrder 和 UglifyJS plugins 都是內置插件,你須要作的只是安裝它們
npm install --save-dev extract-text-webpack-plugin
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: __dirname + "/app/main.js", output: { path: __dirname + "/build", filename: "bundle.js" }, module: { loaders: [ { test: /\.json$/, loader: "json" }, { test: /\.js$/, exclude: /node_modules/, loader: 'babel' }, { test: /\.css$/, loader: ExtractTextPlugin.extract('style', 'css?modules!postcss') } ] }, postcss: [ require('autoprefixer') ], plugins: [ new HtmlWebpackPlugin({ template: __dirname + "/app/index.tmpl.html" }), new webpack.optimize.OccurenceOrderPlugin(), new webpack.optimize.UglifyJsPlugin(), new ExtractTextPlugin("style.css") ] }
webpack能夠把一個哈希值添加到打包的文件名中,使用方法以下,添加特殊的字符串混合體([name], [id] and [hash])到輸出文件名前
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: __dirname + "/app/main.js", output: { path: __dirname + "/build", filename: "[name]-[hash].js" }, module: { loaders: [ { test: /\.json$/, loader: "json" }, { test: /\.js$/, exclude: /node_modules/, loader: 'babel' }, { test: /\.css$/, loader: ExtractTextPlugin.extract('style', 'css?modules!postcss') } ] }, postcss: [ require('autoprefixer') ], plugins: [ new HtmlWebpackPlugin({ template: __dirname + "/app/index.tmpl.html" }), new webpack.optimize.OccurenceOrderPlugin(), new webpack.optimize.UglifyJsPlugin(), new ExtractTextPlugin("[name]-[hash].css") ] }
var path = require('path'); var webpack = require('webpack'); /* extract-text-webpack-plugin插件, 有了它就能夠將你的樣式提取到單獨的css文件裏, 不再用擔憂樣式會被打包到js文件裏了。 */ var ExtractTextPlugin = require('extract-text-webpack-plugin'); /* html-webpack-plugin插件,重中之重,webpack中生成HTML的插件, 具體能夠去這裏查看https://www.npmjs.com/package/html-webpack-plugin */ var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { //配置入口文件,有幾個寫幾個 index: './src/js/page/index.js', list: './src/js/page/list.js', about: './src/js/page/about.js', }, output: { path: path.join(__dirname, 'dist'), //輸出目錄的配置,模板、樣式、腳本、圖片等資源的路徑配置都相對於它 publicPath: '/dist/', //模板、樣式、腳本、圖片等資源對應的server上的路徑 filename: 'js/[name].js', //每一個頁面對應的主js的生成配置 chunkFilename: 'js/[id].chunk.js' //chunk生成的配置 }, module: { loaders: [ //加載器,關於各個加載器的參數配置,可自行搜索之。 { test: /\.css$/, //配置css的抽取器、加載器。'-loader'能夠省去 loader: ExtractTextPlugin.extract('style-loader', 'css-loader') }, { test: /\.less$/, //配置less的抽取器、加載器。中間!有必要解釋一下, //根據從右到左的順序依次調用less、css加載器,前一個的輸出是後一個的輸入 //你也能夠開發本身的loader喲。有關loader的寫法可自行谷歌之。 loader: ExtractTextPlugin.extract('css!less') }, { //html模板加載器,能夠處理引用的靜態資源,默認配置參數attrs=img:src,處理圖片的src引用的資源 //好比你配置,attrs=img:src img:data-src就能夠一併處理data-src引用的資源了,就像下面這樣 test: /\.html$/, loader: "html?attrs=img:src img:data-src" }, { //文件加載器,處理文件靜態資源 test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file-loader?name=./fonts/[name].[ext]' }, { //圖片加載器,雷同file-loader,更適合圖片,能夠將較小的圖片轉成base64,減小http請求 //以下配置,將小於8192byte的圖片轉成base64碼 test: /\.(png|jpg|gif)$/, loader: 'url-loader?limit=8192&name=./img/[hash].[ext]' } ] }, plugins: [ new webpack.ProvidePlugin({ //加載jq $: 'jquery' }), new webpack.optimize.CommonsChunkPlugin({ name: 'vendors', // 將公共模塊提取,生成名爲`vendors`的chunk chunks: ['index','list','about'], //提取哪些模塊共有的部分 minChunks: 3 // 提取至少3個模塊共有的部分 }), new ExtractTextPlugin('css/[name].css'), //單獨使用link標籤加載css並設置路徑,相對於output配置中的publickPath //HtmlWebpackPlugin,模板生成相關的配置,每一個對於一個頁面的配置,有幾個寫幾個 new HtmlWebpackPlugin({ //根據模板插入css/js等生成最終HTML favicon: './src/img/favicon.ico', //favicon路徑,經過webpack引入同時能夠生成hash值 filename: './view/index.html', //生成的html存放路徑,相對於path template: './src/view/index.html', //html模板路徑 inject: 'body', //js插入的位置,true/'head'/'body'/false hash: true, //爲靜態資源生成hash值 chunks: ['vendors', 'index'],//須要引入的chunk,不配置就會引入全部頁面的資源 minify: { //壓縮HTML文件 removeComments: true, //移除HTML中的註釋 collapseWhitespace: false //刪除空白符與換行符 } }), new HtmlWebpackPlugin({ //根據模板插入css/js等生成最終HTML favicon: './src/img/favicon.ico', //favicon路徑,經過webpack引入同時能夠生成hash值 filename: './view/list.html', //生成的html存放路徑,相對於path template: './src/view/list.html', //html模板路徑 inject: true, //js插入的位置,true/'head'/'body'/false hash: true, //爲靜態資源生成hash值 chunks: ['vendors', 'list'],//須要引入的chunk,不配置就會引入全部頁面的資源 minify: { //壓縮HTML文件 removeComments: true, //移除HTML中的註釋 collapseWhitespace: false //刪除空白符與換行符 } }), new HtmlWebpackPlugin({ //根據模板插入css/js等生成最終HTML favicon: './src/img/favicon.ico', //favicon路徑,經過webpack引入同時能夠生成hash值 filename: './view/about.html', //生成的html存放路徑,相對於path template: './src/view/about.html', //html模板路徑 inject: true, //js插入的位置,true/'head'/'body'/false hash: true, //爲靜態資源生成hash值 chunks: ['vendors', 'about'],//須要引入的chunk,不配置就會引入全部頁面的資源 minify: { //壓縮HTML文件 removeComments: true, //移除HTML中的註釋 collapseWhitespace: false //刪除空白符與換行符 } }), new webpack.HotModuleReplacementPlugin() //熱加載 ], //使用webpack-dev-server,提升開發效率 devServer: { contentBase: './', host: 'localhost', port: 9090, //默認8080 inline: true, //能夠監控js變化 hot: true, //熱啓動 } };
本文學習自: