Webpack 是一個前端資源加載/打包工具,咱們部門的一條主要技術棧就是Webpack+React+ES6+node,雖然以前本身作我的項目也接觸好屢次Webpack,可是本身並無研讀總結過Webpack的知識點,讀了wepack-demos,這些demos雖然是基於webpack@1.x的,可是舉例得蠻簡潔明瞭,因此此次就簡單翻譯此文的一些重點。javascript
Webpack是一個前端資源加載/打包工具,只須要相對簡單的配置就能夠提供前端工程化須要的各類功能,而且若是有須要它還能夠被整合到其餘好比 Grunt / Gulp 的工做流。css
安裝 Webpack:npm install -g webpack。
html
Webpack 使用一個名爲 webpack.config.js
的配置文件。前端
// webpack.config.js module.exports = { entry: './main.js', output: { filename: 'bundle.js' } };
一些你應該知道的命令:java
在開發應用程序時,能夠在package.json文件中編寫scripts字段,以下所示:node
// package.json { // ... "scripts": { "dev": "webpack-dev-server --devtool eval --progress --colors", "deploy": "NODE_ENV=production webpack -p" }, // ... }
入口文件是一個Webpack將會讀取它並將它編譯成bundle.js的文件react
demo01:單個入口文件:jquery
// webpack.config.js module.exports = { entry: './main.js', output: { filename: 'bundle.js' } };
demo02:多個入口文件:(它對多頁面app是很是有用的)webpack
// index.html <html> <body> <script src="bundle1.js"></script> <script src="bundle2.js"></script> </body> </html> // webpack.config.js module.exports = { entry: { bundle1: './main1.js', bundle2: './main2.js' }, output: { filename: '[name].js' } };
加載器是預處理器,它轉換您的應用程序的資源文件(更多信息)。例如,Babel-loader能夠將JSX / ES6文件轉換爲JS文件。官方文檔有一個完整的加載器列表。git
// webpack.config.js module: { loaders:[ { test: /\.js[x]?$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react' }, ] } 或者 module: { loaders: [ { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: { presets: ['es2015', 'react'] } } ] }
Webpack容許您在JS文件中引用CSS,而後使用CSS-loader預處理CSS文件。
// main.js require('./app.css');
// webpack.config.js module.exports = { entry: './main.js', output: { filename: 'bundle.js' }, module: { loaders:[ { test: /\.css$/, loader: 'style-loader!css-loader' }, ] } };
注意,你必須使用兩個加載器來轉換CSS文件。首先是CSS-loader讀取CSS文件,另外一個是Style-loader將Style標籤插入HTML頁面。不一樣的裝載器經過感嘆號(!)連接。
啓動服務器後,index.html將具備內部樣式表。(demo04)
// main.js var img1 = document.createElement("img"); img1.src = require("./small.png"); document.body.appendChild(img1); var img2 = document.createElement("img"); img2.src = require("./big.png"); document.body.appendChild(img2); // index.html <html> <body> <script type="text/javascript" src="bundle.js"></script> </body> </html> // webpack.config.js module.exports = { entry: './main.js', output: { filename: 'bundle.js' }, module: { loaders:[ { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' } ] } };
url-loader轉換圖像文件。若是圖像大小小於8192字節,則將其轉換爲數據URL;不然,它將被轉換爲正常的URL。如你所見,問號(?)用於將參數傳遞到加載器。
啓動服務器後,small.png和big.png將有如下URL。
<img src="data:image/png;base64,iVBOR...uQmCC"> <img src="4853ca667a2b8b8844eb2693ac1b2578.png">
Webpack有一個插件系統來擴展其功能。例如,UglifyJs Plugin將縮小輸出(bundle.js)JS代碼。(demo07)
// webpack.config.js var webpack = require('webpack'); var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin; module.exports = { entry: './main.js', output: { filename: 'bundle.js' }, plugins: [ new uglifyJsPlugin({ compress: { warnings: false } }) ] };
壓縮的效果以下:
// 壓縮前 var longVariableName = 'Hello'; longVariableName += ' World'; document.write('<h1>' + longVariableName + '</h1>'); // 壓縮後 var o="Hello";o+=" World",document.write("<h1>"+o+"</h1>")
此演示向您演示如何加載第三方插件。 html-webpack-plugin能夠爲您建立index.html,而且當Webpack加載時,open-browser-webpack-plugin能夠打開一個新的瀏覽器選項卡。
// main.js document.write('<h1>Hello World</h1>'); // webpack.config.js var HtmlwebpackPlugin = require('html-webpack-plugin'); var OpenBrowserPlugin = require('open-browser-webpack-plugin'); module.exports = { entry: './main.js', output: { filename: 'bundle.js' }, plugins: [ new HtmlwebpackPlugin({ title: 'Webpack-demos', filename: 'index.html' }), new OpenBrowserPlugin({ url: 'http://localhost:8080' }) ] };
您能夠僅在具備環境標誌的開發環境中啓用一些代碼(demo09)
// main.js document.write('<h1>Hello World</h1>'); if (__DEV__) { document.write(new Date()); } // index.html <html> <body> <script src="bundle.js"></script> </body> </html> // webpack.config.js var webpack = require('webpack'); var devFlagPlugin = new webpack.DefinePlugin({ __DEV__: JSON.stringify(JSON.parse(process.env.DEBUG || 'false')) }); module.exports = { entry: './main.js', output: { filename: 'bundle.js' }, plugins: [devFlagPlugin] };
而後如今將環境變量傳遞到webpack。
# Linux & Mac $ env DEBUG=true webpack-dev-server # Windows $ set DEBUG=true $ webpack-dev-server
當多腳本具備公共塊時,可使用CommonsChunkPlugin將公共部分提取到單獨的文件中。
// main1.jsx var React = require('react'); var ReactDOM = require('react-dom'); ReactDOM.render( <h1>Hello World</h1>, document.getElementById('a') ); // main2.jsx var React = require('react'); var ReactDOM = require('react-dom'); ReactDOM.render( <h2>Hello Webpack</h2>, document.getElementById('b') ); // index.html <html> <body> <div id="a"></div> <div id="b"></div> <script src="init.js"></script> <script src="bundle1.js"></script> <script src="bundle2.js"></script> </body> </html> // webpack.config.js var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { entry: { bundle1: './main1.jsx', bundle2: './main2.jsx' }, output: { filename: '[name].js' }, module: { loaders:[ { test: /\.js[x]?$/, exclude: /node_modules/, loader: 'babel-loader', query: { presets: ['es2015', 'react'] } }, ] }, plugins: [ new CommonsChunkPlugin('init.js') ] }
您還可使用CommonsChunkPlugin從腳本中將供應商庫提取到單獨的文件中。(優化代碼層面)
// main.js var $ = require('jquery'); $('h1').text('Hello World'); // index.html <html> <body> <h1></h1> <script src="vendor.js"></script> <script src="bundle.js"></script> </body> </html> // webpack.config.js var webpack = require('webpack'); module.exports = { entry: { app: './main.js', vendor: ['jquery'], }, output: { filename: 'bundle.js' }, plugins: [ new webpack.optimize.CommonsChunkPlugin(/* chunkName= */'vendor', /* filename= */'vendor.js') ] };
若是你想要一個模塊做爲變量在每一個模塊,如使$和jQuery可用在每一個模塊沒有寫require(「jquery」)。你應該使用ProvidePlugin(官方文檔)。
// main.js $('h1').text('Hello World'); // webpack.config.js var webpack = require('webpack'); module.exports = { entry: { app: './main.js' }, output: { filename: 'bundle.js' }, plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", "window.jQuery": "jquery" }) ] };
熱模塊替換(HMR)交換,添加或刪除模塊,而應用程序正在運行,而沒有頁面從新加載。
您有兩種方法經過webpack-dev-server啓用熱模塊更換。
(1)在命令行中指定--hot和--inline
$ webpack-dev-server --hot --inline
選項的含義:
(2)修改webpack.config.js文件(demo15)
// webpack.config.js var webpack = require('webpack'); var path = require('path'); module.exports = { entry: [ 'webpack/hot/dev-server', 'webpack-dev-server/client?http://localhost:8080', './index.js' ], output: { filename: 'bundle.js', publicPath: '/static/' }, plugins: [ new webpack.HotModuleReplacementPlugin() ], module: { loaders: [{ test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader', query: { presets: ['es2015', 'react'] }, include: path.join(__dirname, '.') }] } };
// App.js import React, { Component } from 'react'; export default class App extends Component { render() { return ( <h1>Hello World</h1> ); } } // index.js import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; ReactDOM.render(<App />, document.getElementById('root')); // index.html <html> <body> <div id='root'></div> <script src="/static/bundle.js"></script> </body> </html>
下回會學習總結webpack2的配置相關總結,有不錯的文章歡迎分享。