ps:每一個案例都是基於前一個案例改造的javascript
webpack入門(1) 戳這裏css
案例源碼戳這裏html
自動加載模塊java
new webpack.ProvidePlugin()node
上面的案例太複雜,下面再新建一個簡單的項目來說解react
新建一個項目,以下jquery
[webpack] |-- src |-- index.html |-- index.less |-- index.js |-- package.json |-- webpack.config.js
webpack/package.jsonwebpack
{ "name": "webpack", "version": "1.0.0", "description": "", "scripts": { "start": "webpack-dev-server --content-base build --inline --hot", "build": "webpack -p", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-es2015": "^6.24.1", "css-loader": "^0.28.7", "extract-text-webpack-plugin": "^3.0.2", "file-loader": "^1.1.5", "html-webpack-plugin": "^2.30.1", "jquery": "^3.2.1", "less": "^2.7.3", "less-loader": "^4.0.5", "style-loader": "^0.19.0", "url-loader": "^0.6.2", "webpack": "^3.10.0", "webpack-dev-server": "^2.9.5" } }
webpack/webpack.config.jsgit
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { entry: { // 入口文件地址 index: './src/index.js', jquery: [ "jquery" ] }, output: { // 出口 path: __dirname + "/build", // 打包後的文件存放路徑 filename: '[name].js' // 文件名,name即爲entry的key }, module: { loaders: [ { test: /\.js$/, // js-loader loader: 'babel-loader?presets=es2015' }, { test: /\.css$/, // css-loader loader: ExtractTextPlugin.extract('css-loader') }, { test: /\.less/, // less-loader loaders: ExtractTextPlugin.extract('css-loader!less-loader') }, { test: /\.(png|jpg)$/, // img-loader loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' } ], }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', // 生成的的html文件名 template: './src/index.html', // 被打包的html路徑 chunks: ['index', 'jquery'] // 須要引入的js,對應entry的key }), new ExtractTextPlugin({ // 單獨打包css filename: '[name].css' }), new webpack.optimize.CommonsChunkPlugin({ name: 'jquery' // 對應entry的key }), new webpack.ProvidePlugin({ // 全局引入jquery $: 'jquery' }) ] }
webpack/src/index.htmlgithub
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>webpackDemo</title> </head> <body> </body> </html>
webpack/src/index.less
body { background: lightpink; }
webpack/src/index.js
import './index.less'; $('body').prepend('hi');
在webpack.config.js裏設置了全局引入jquery,這裏就不須要
import $ from 'jquery'
能夠直接用 $
$ npm run start , 打開 http://localhost:8080/index.html , 效果以下
點擊這裏下載 案例17 使用的iconfont文件,如下簡稱「案例17壓縮包」
新增文件 iconfont.less 和 iconfont.ttf(案例17壓縮包裏的iconfont.ttf),將index.less移動至css文件夾下,以下
[webpack] |-- src |-- images |-- iconfont.ttf |-- css |-- iconfont.less |-- index.less |-- index.html |-- index.js |-- package.json |-- webpack.config.js
webpack/src/css/iconfont.less
@font-face { font-family: "iconfont"; src: url('../images/iconfont.ttf') format('truetype'); } .iconfont { font-family: "iconfont" !important; font-size: 16px; font-style: normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .icon-love:before { content: "\e612"; }
webpack/src/css/index.less
@import './iconfont.less'; body { background: lightpink; .iconfont { font-size: 50px; } }
webpack/src/index.js
import './css/index.less'; $('body').prepend('<i class="iconfont icon-love"></i>');
webpack/webpack.config.js
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { entry: { // 入口文件地址 index: './src/index.js', jquery: [ "jquery" ] }, output: { // 出口 path: __dirname + "/build", // 打包後的文件存放路徑 filename: '[name].js' // 文件名,name即爲entry的key }, module: { loaders: [ { test: /\.js$/, // js-loader loader: 'babel-loader?presets=es2015' }, { test: /\.css$/, // css-loader loader: ExtractTextPlugin.extract('css-loader') }, { test: /\.less/, // less-loader loaders: ExtractTextPlugin.extract('css-loader!less-loader') }, { test: /\.(png|jpg|ttf)$/, // img-loader loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' } ], }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', // 生成的的html文件名 template: './src/index.html', // 被打包的html路徑 chunks: ['index', 'jquery'] // 須要引入的js,對應entry的key }), new ExtractTextPlugin({ // 單獨打包css filename: '[name].css' }), new webpack.optimize.CommonsChunkPlugin({ name: 'jquery' // 對應entry的key }), new webpack.ProvidePlugin({ // 全局引入jquery $: 'jquery' }) ] }
本案例只引入了ttf,其餘能夠相似添加
{ test: /\.(png|jpg|ttf|svg|eot|woff)$/, // img-loader loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' }
$ npm run start , 打開 http://localhost:8080/index.html ,效果以下
$ npm run build , iconfont.ttf文件小會轉爲base64直接打包到index.css裏,若是文件比較大,則會單獨打包到webpack/build/images/iconfont.ttf
externals 配置選項提供了「從輸出的 bundle 中排除依賴」的方法。
好比 jquery 但願經過 cdn 的方式引入,代碼裏依舊用 import 的方式來使用,可是又不但願被打包。
webpack/src/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>webpackDemo</title> </head> <body> <script src="https://code.jquery.com/jquery-3.1.0.js"></script> </body> </html>
webpack/src/index.js
import $ from 'jquery'; import './css/index.less'; $('body').prepend('<i class="iconfont icon-love"></i>');
webpack/webpack.config.js
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { entry: { // 入口文件地址 index: './src/index.js' }, output: { // 出口 path: __dirname + "/build", // 打包後的文件存放路徑 filename: '[name].js' // 文件名,name即爲entry的key }, externals: { jquery: 'jQuery' // jquery不被webpack編譯到文件中 }, module: { loaders: [ { test: /\.js$/, // js-loader loader: 'babel-loader?presets=es2015' }, { test: /\.css$/, // css-loader loader: ExtractTextPlugin.extract('css-loader') }, { test: /\.less/, // less-loader loaders: ExtractTextPlugin.extract('css-loader!less-loader') }, { test: /\.(png|jpg|ttf)$/, // img-loader loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' } ], }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', // 生成的的html文件名 template: './src/index.html', // 被打包的html路徑 chunks: ['index'] // 須要引入的js,對應entry的key }), new ExtractTextPlugin({ // 單獨打包css filename: '[name].css' }) ] }
運行 $ npm run build , 生成文件目錄以下
[webpack] |-- build |-- index.css |-- index.html |-- index.js
安裝依賴
$ npm i babel-preset-react react react-dom --save-dev
webpack/src/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>webpackDemo</title> </head> <body> <div id="root"></div> </body> </html>
webpack/src/index.js
import React from 'react'; import ReactDOM from 'react-dom'; import './css/index.less'; class Demo extends React.Component { render() { return ( <i className="iconfont icon-love" /> ); } } ReactDOM.render( <Demo />, document.getElementById('root') );
webpack/webpack.config.js
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { entry: { // 入口文件地址 index: './src/index.js' }, output: { // 出口 path: __dirname + "/build", // 打包後的文件存放路徑 filename: '[name].js' // 文件名,name即爲entry的key }, module: { loaders: [ { test: /\.(js|jsx)$/, // js-loader loader: 'babel-loader?presets[]=es2015&presets[]=react' }, { test: /\.css$/, // css-loader loader: ExtractTextPlugin.extract('css-loader') }, { test: /\.less/, // less-loader loaders: ExtractTextPlugin.extract('css-loader!less-loader') }, { test: /\.(png|jpg|ttf)$/, // img-loader loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' } ], }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', // 生成的的html文件名 template: './src/index.html', // 被打包的html路徑 chunks: ['index'] // 須要引入的js,對應entry的key }), new ExtractTextPlugin({ // 單獨打包css filename: '[name].css' }) ] }
須要babel-preset-react插件來編譯React
運行 $ npm run start , 打開 http://localhost:8080/ ,能看到效果
運行 $ npm run build ,打包文件目錄以下:
[webpack] |-- build |-- index.css |-- index.html |-- index.js
react被打包到webpack/build/index.js裏去了
webpack/src/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>webpackDemo</title> </head> <body> <div id="root"></div> <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script> <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script> </body> </html>
webpack/webpack.config.js
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { entry: { // 入口文件地址 index: './src/index.js' }, output: { // 出口 path: __dirname + "/build", // 打包後的文件存放路徑 filename: '[name].js' // 文件名,name即爲entry的key }, externals: { 'react': 'React', 'react-dom': 'ReactDOM' }, module: { loaders: [ { test: /\.(js|jsx)$/, // js-loader loader: 'babel-loader?presets[]=es2015&presets[]=react' }, { test: /\.css$/, // css-loader loader: ExtractTextPlugin.extract('css-loader') }, { test: /\.less/, // less-loader loaders: ExtractTextPlugin.extract('css-loader!less-loader') }, { test: /\.(png|jpg|ttf)$/, // img-loader loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' } ], }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', // 生成的的html文件名 template: './src/index.html', // 被打包的html路徑 chunks: ['index'] // 須要引入的js,對應entry的key }), new ExtractTextPlugin({ // 單獨打包css filename: '[name].css' }) ] }
這樣 react 就不會被打包入 webpack/build/index.js
新建一個項目以下
[webpack] |-- package.json |-- webpack.config.js |-- src |-- index.html |-- index.js |-- images |-- SpongeBob.jpg |-- css |-- index.less
本案例用到的圖片 SpongeBob.jpg 戳這裏
webpack/package.json
{ "name": "webpack", "version": "1.0.0", "description": "", "scripts": { "start": "webpack-dev-server", "build": "webpack -p" }, "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "css-loader": "^0.28.7", "extract-text-webpack-plugin": "^3.0.2", "file-loader": "^1.1.5", "html-webpack-plugin": "^2.30.1", "jquery": "^3.2.1", "less": "^2.7.3", "less-loader": "^4.0.5", "style-loader": "^0.19.0", "url-loader": "^0.6.2", "webpack": "^3.10.0", "webpack-dev-server": "^2.9.5" } }
webpack/webpack.config.js
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { entry: { // 入口文件地址 index: './src/index.js' }, output: { // 出口 path: __dirname + "/build", // 打包後的文件存放路徑 filename: '[name].js' // 文件名,name即爲entry的key }, externals: { 'jquery': 'jQuery', // 不打包jquery }, module: { loaders: [ { test: /\.(js|jsx)$/, // js-loader loader: 'babel-loader?presets[]=es2015&presets[]=react' }, { test: /\.less/, // less-loader loaders: ExtractTextPlugin.extract('css-loader!less-loader') }, { test: /\.(png|jpg|ttf)$/, // img-loader loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' } ], }, devServer: { contentBase: './build', inline: true, hot: true }, plugins: [ new webpack.HotModuleReplacementPlugin(), // 啓用熱替換模塊 new HtmlWebpackPlugin({ filename: 'index.html', // 生成的的html文件名 template: './src/index.html', // 被打包的html路徑 chunks: ['index'] // 須要引入的js,對應entry的key }), new ExtractTextPlugin({ // 單獨打包css filename: '[name].css' }) ] }
webpack/src/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>webpackDemo</title> </head> <body> <script src="https://code.jquery.com/jquery-3.1.0.js"></script> </body> </html>
webpack/src/css/index.less
body { background: url(../images/SpongeBob.jpg) no-repeat; color: blue; }
webpack/src/index.js
import './css/index.less'; $('body').prepend('hi')
package.json 對比
// 案例16 "scripts": { "start": "webpack-dev-server --content-base build --inline --hot", } // 案例21 "scripts": { "start": "webpack-dev-server", }
案例21 中 webpack-dev-server 後的參數,改成在 webapck.config.js 中設置
{ devServer: { contentBase: './build', inline: true, hot: true }, plugins: [ new webpack.HotModuleReplacementPlugin() ] }
$ npm run start , 打開 http://localhost:8080/ , 效果以下
{ devServer: { before: (app) =>{ app.get('/init.json', function(req, res) { res.json({ title: 'webpack' }); }); } } }
webpack/webpack.config.js
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { entry: { // 入口文件地址 index: './src/index.js' }, output: { // 出口 path: __dirname + "/build", // 打包後的文件存放路徑 filename: '[name].js' // 文件名,name即爲entry的key }, externals: { 'jquery': 'jQuery', // 不打包jquery }, module: { loaders: [ { test: /\.(js|jsx)$/, // js-loader loader: 'babel-loader?presets[]=es2015&presets[]=react' }, { test: /\.less/, // less-loader loaders: ExtractTextPlugin.extract('css-loader!less-loader') }, { test: /\.(png|jpg|ttf)$/, // img-loader loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' } ], }, devServer: { contentBase: './build', inline: true, hot: true, before: (app) =>{ app.get('/init.json', function(req, res) { res.json({ title: 'webpack' }); }); } }, plugins: [ new webpack.HotModuleReplacementPlugin(), // 啓用熱替換模塊 new HtmlWebpackPlugin({ filename: 'index.html', // 生成的的html文件名 template: './src/index.html', // 被打包的html路徑 chunks: ['index'] // 須要引入的js,對應entry的key }), new ExtractTextPlugin({ // 單獨打包css filename: '[name].css' }) ] }
webpack/src/index.js
import './css/index.less'; $.ajax({ url: '/init.json', data: {}, type: 'GET', success: (d = {}) => { $('body').prepend(d.title); }, error: () => { $('body').prepend('ajax error'); } });
$ npm run start , 打開 http://localhost:8080/index.html , 效果以下
若是是 post 請求,webpack.config.js 以下
{ devServer: { before: (app) =>{ app.post('/init.json', function(req, res) { res.json({ title: 'webpack' }); }); } } }
固然,也能夠不在 res.json() 中直接寫 mock 數據,能夠在外面命名變量,或者從其餘文件引入
var mock_init = require('xxxxx'); var mock_user = { title: 'webpack' }; module.exports = { devServer: { before: (app) =>{ app.post('/init.json', function(req, res) { res.json(mock_init); }); app.post('/user.json', function(req, res) { res.json(mock_user); }); } } }
DefinePlugin 能夠把命令行的環境變量帶到瀏覽器端。
new webpack.DefinePlugin()
環境變量在不少狀況都會使用,這裏舉一個例子,好比咱們本地 mock 數據時,請求都是 "localhost:8080" 開頭的,可是到線上了則是 "http://a.com" 和 "http://b.com" , 這個時候就可使用 DefinePlugin 來解決
webpack/package.json
{ "name": "webpack", "version": "1.0.0", "description": "", "scripts": { "start": "NODE_ENV=mock webpack-dev-server", "prod": "NODE_ENV=prod webpack-dev-server", "build-start": "NODE_ENV=mock webpack -p", "build-prod": "NODE_ENV=prod webpack -p" }, "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "css-loader": "^0.28.7", "extract-text-webpack-plugin": "^3.0.2", "file-loader": "^1.1.5", "html-webpack-plugin": "^2.30.1", "jquery": "^3.2.1", "less": "^2.7.3", "less-loader": "^4.0.5", "style-loader": "^0.19.0", "url-loader": "^0.6.2", "webpack": "^3.10.0", "webpack-dev-server": "^2.9.5" } }
"NODE_ENV=xxx" , 能夠定義不一樣環境的 NODE_ENV
start 和 build-start , 是咱們本地開發時使用 ; prod 和 build-prod , 是線上環境使用
webpack/webpack.config.js
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); console.log('----------- NODE_ENV ----------- : ', process.env.NODE_ENV) module.exports = { entry: { // 入口文件地址 index: './src/index.js' }, output: { // 出口 path: __dirname + "/build", // 打包後的文件存放路徑 filename: '[name].js' // 文件名,name即爲entry的key }, externals: { 'jquery': 'jQuery', // 不打包jquery }, module: { loaders: [ { test: /\.(js|jsx)$/, // js-loader loader: 'babel-loader?presets[]=es2015&presets[]=react' }, { test: /\.less/, // less-loader loaders: ExtractTextPlugin.extract('css-loader!less-loader') }, { test: /\.(png|jpg|ttf)$/, // img-loader loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' } ], }, devServer: { contentBase: './build', inline: true, hot: true, before: (app) =>{ app.get('/init.json', function(req, res) { res.json({ title: 'webpack' }); }); } }, plugins: [ new webpack.HotModuleReplacementPlugin(), // 啓用熱替換模塊 new HtmlWebpackPlugin({ filename: 'index.html', // 生成的的html文件名 template: './src/index.html', // 被打包的html路徑 chunks: ['index'] // 須要引入的js,對應entry的key }), new ExtractTextPlugin({ // 單獨打包css filename: '[name].css' }) ] }
經過 process.env.NODE_ENV 變量拿到值
$ npm run start , 效果以下
$ npm run prod , 效果以下
webpack/webpack.config.js
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); const checkHost = { "mock": { "A_HOST": "http://localhost:8080", "B_HOST": "http://localhost:8080", }, "prod": { "A_HOST": "http://a.com", "B_HOST": "http://b.com", } } var checkHostKey = checkHost[process.env.NODE_ENV] ? process.env.NODE_ENV : 'mock'; var checkHostContent = checkHost[checkHostKey]; for (i in checkHostContent) { checkHostContent[i] = JSON.stringify(checkHostContent[i]); } module.exports = { entry: { // 入口文件地址 index: './src/index.js' }, output: { // 出口 path: __dirname + "/build", // 打包後的文件存放路徑 filename: '[name].js' // 文件名,name即爲entry的key }, externals: { 'jquery': 'jQuery', // 不打包jquery }, module: { loaders: [ { test: /\.(js|jsx)$/, // js-loader loader: 'babel-loader?presets[]=es2015&presets[]=react' }, { test: /\.less/, // less-loader loaders: ExtractTextPlugin.extract('css-loader!less-loader') }, { test: /\.(png|jpg|ttf)$/, // img-loader loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' } ], }, devServer: { contentBase: './build', inline: true, hot: true, before: (app) =>{ app.get('/init.json', function(req, res) { res.json({ title: 'webpack' }); }); } }, plugins: [ new webpack.DefinePlugin(checkHostContent), new webpack.HotModuleReplacementPlugin(), // 啓用熱替換模塊 new HtmlWebpackPlugin({ filename: 'index.html', // 生成的的html文件名 template: './src/index.html', // 被打包的html路徑 chunks: ['index'] // 須要引入的js,對應entry的key }), new ExtractTextPlugin({ // 單獨打包css filename: '[name].css' }) ] }
分析以下
const checkHost = { "mock": { // 本地 mock 數據使用 "A_HOST": "http://localhost:8080", "B_HOST": "http://localhost:8080", }, "prod": { // 線上環境使用 "A_HOST": "http://a.com", "B_HOST": "http://b.com", } } // 檢查 checkHost[process.env.NODE_ENV] 是否存在,不存在時,將rocess.env.NODE_ENV 設置爲 mock var checkHostKey = checkHost[process.env.NODE_ENV] ? process.env.NODE_ENV : 'mock'; // checkHostContent 至關因而 checkHost.mock 或 checkHost.prod var checkHostContent = checkHost[checkHostKey]; // 若是 DefinePlugin 鍵值是一個字符串,它會被看成一個代碼片斷來使用,須要 JSON.stringify() 處理 for (i in checkHostContent) { checkHostContent[i] = JSON.stringify(checkHostContent[i]); } // 將處理好的 checkHostContent 放入 module.exports = { plugins: [new webpack.DefinePlugin(checkHostContent)] }
這一部分代碼,將咱們要用到的 A_HOST 和 B_HOST 都處理好,再放入new webpack.DefinePlugin(),拿 prod 舉例,至關於處理成
module.exports = { plugins: [new webpack.DefinePlugin({ A_HOST: JSON.stringify("http://a.com"), B_HOST: JSON.stringify("http://b.com"), })] }
webpack/src/index.js
import './css/index.less'; console.log(A_HOST, B_HOST) $.ajax({ url: `${A_HOST}/init.json`, data: {}, type: 'GET', success: (d = {}) => { $('body').prepend(d.title); }, error: () => { $('body').prepend('ajax error'); } });
$ npm run start , 效果以下
$ npm run prod , 效果以下
固然,也能夠直接寫兩個 webpack.config.js 文件,這裏就貼一下代碼,不具體寫案例了
// webpack.start.config.js module.exports = { plugins: [new webpack.DefinePlugin({ A_HOST: JSON.stringify("http://localhost:8080"), B_HOST: JSON.stringify("http://localhost:8080"), })] } // webpack.prod.config.js module.exports = { plugins: [new webpack.DefinePlugin({ A_HOST: JSON.stringify("http://a.com"), B_HOST: JSON.stringify("http://b.com"), })] } // package.json { "scripts": { "start": "webpack-dev-server --config webpack.start.config.js", "prod": "webpack-dev-server --config webpack.prod.config.js", "build-start": "webpack -p --config webpack.start.config.js", "build-prod": "webpack -p --config webpack.prod.config.js" } }
新增 webpack/server.js , 目錄以下
[webpack] |-- server.js |-- package.json |-- webpack.config.js |-- src |-- index.html |-- index.js |-- images |-- SpongeBob.jpg |-- css |-- index.less
webpack/webpack.config.js
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); const checkHost = { "mock": { // 本地 mock 數據使用 "A_HOST": "http://localhost:8080", "B_HOST": "http://localhost:8080", }, "prod": { // 線上環境使用 "A_HOST": "http://a.com", "B_HOST": "http://b.com", } } // 檢查 process.env.NODE_ENV 是否和 checkHost 裏的對應 var checkHostKey = checkHost[process.env.NODE_ENV] ? process.env.NODE_ENV : 'mock'; // checkHostContent 至關因而 checkHost.mock 或 checkHost.prod var checkHostContent = checkHost[checkHostKey]; // 若是 DefinePlugin 鍵值是是一個字符串,它會被看成一個代碼片斷來使用,須要 JSON.stringify() 處理 for (i in checkHostContent) { checkHostContent[i] = JSON.stringify(checkHostContent[i]); } module.exports = { entry: { // 入口文件地址 index: ['./src/index.js'] }, output: { // 出口 path: __dirname + "/build", // 打包後的文件存放路徑 filename: '[name].js' // 文件名,name即爲entry的key }, externals: { 'jquery': 'jQuery', // 不打包jquery }, module: { loaders: [ { test: /\.(js|jsx)$/, // js-loader loader: 'babel-loader?presets[]=es2015&presets[]=react' }, { test: /\.less/, // less-loader loaders: ExtractTextPlugin.extract('css-loader!less-loader') }, { test: /\.(png|jpg|ttf)$/, // img-loader loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' } ], }, plugins: [ new webpack.DefinePlugin(checkHostContent), // 將處理好的 checkHostContent 放入 new webpack.HotModuleReplacementPlugin(), // 啓用熱替換模塊 new HtmlWebpackPlugin({ filename: 'index.html', // 生成的的html文件名 template: './src/index.html', // 被打包的html路徑 chunks: ['index'] // 須要引入的js,對應entry的key }), new ExtractTextPlugin({ // 單獨打包css filename: '[name].css' }) ] }
將 devServer 刪除 , entry.index 改成 array 寫法
webpack/server.js
// 引入 webpack 和 webpack-dev-server var webpack = require('webpack'); var WebpackDevServer = require('webpack-dev-server'); // 引入 webpack 的配置 var config = require('./webpack.config.js'); // 添加 webpack-dev-server 的客戶端入口文件到 webpack 的配置中 // 經過 unshift 方法,將 webpack-dev-server/client?http://«path»:«port»/ 插入到 webpack-dev-server 配置的 entry.index 中 config.entry.index.unshift("webpack-dev-server/client?http://localhost:8080/"); // compiler = webpack({ webpack 的配置 }) var compiler = webpack(config); // server = new WebpackDevServer(compiler, { devServer 的配置 }) var server = new WebpackDevServer(compiler, { contentBase: './build', inline: true, hot: true, before: (app) =>{ app.get('/init.json', function(req, res) { res.json({ title: 'webpack' }); }); } }); server.listen(8080, "localhost", function() {});
webpack-dev-server 的配置裏沒有 inline : true 這個配置項, 由於 webpack-dev-server 沒法訪問 webpack 的配置。 所以,用戶必須添加 webpack-dev-server 的客戶端入口文件到 webpack 的配置中,有如下幾種方式(上面案例只寫了一種,其餘你們能夠自行嘗試)
// server.js config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/"); // webpack.config.js { entry: { index: [ 'webpack-dev-server/client?http://localhost:8080/', './src/index.js' ] } } // index.html <script src="http://localhost:8080/webpack-dev-server.js"></script>
webpack/package.json
{ "name": "webpack", "version": "1.0.0", "description": "", "scripts": { "start": "NODE_ENV=mock node server.js", "prod": "NODE_ENV=prod node server.js", "build-start": "NODE_ENV=mock webpack -p", "build-prod": "NODE_ENV=prod webpack -p" }, "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "css-loader": "^0.28.7", "extract-text-webpack-plugin": "^3.0.2", "file-loader": "^1.1.5", "html-webpack-plugin": "^2.30.1", "jquery": "^3.2.1", "less": "^2.7.3", "less-loader": "^4.0.5", "style-loader": "^0.19.0", "url-loader": "^0.6.2", "webpack": "^3.10.0", "webpack-dev-server": "^2.9.5" } }
修改了 scripts.start 和 scripts.prod ,$ npm run start 和 $ npm run prod ,效果和 案例23 同樣
下面介紹一下 loaders 的其餘寫法
webpack/server.js
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); const checkHost = { "mock": { // 本地 mock 數據使用 "A_HOST": "http://localhost:8080", "B_HOST": "http://localhost:8080", }, "prod": { // 線上環境使用 "A_HOST": "http://a.com", "B_HOST": "http://b.com", } } // 檢查 process.env.NODE_ENV 是否和 checkHost 裏的對應 var checkHostKey = checkHost[process.env.NODE_ENV] ? process.env.NODE_ENV : 'mock'; // checkHostContent 至關因而 checkHost.mock 或 checkHost.prod var checkHostContent = checkHost[checkHostKey]; // 若是 DefinePlugin 鍵值是是一個字符串,它會被看成一個代碼片斷來使用,須要 JSON.stringify() 處理 for (i in checkHostContent) { checkHostContent[i] = JSON.stringify(checkHostContent[i]); } module.exports = { entry: { // 入口文件地址 index: ['./src/index.js'] }, output: { // 出口 path: __dirname + "/build", // 打包後的文件存放路徑 filename: '[name].js' // 文件名,name即爲entry的key }, externals: { 'jquery': 'jQuery', // 不打包jquery }, module: { rules: [ // loaders { test: /\.(js|jsx)$/, use: { loader: 'babel-loader', options: { presets: ['es2015', 'react'] } } }, { test: /\.less$/, use: ExtractTextPlugin.extract({ use: [{ loader: "css-loader" }, { loader: "less-loader" }] }) }, { test: /\.(png|jpg|ttf)$/, use: [ { loader: 'url-loader', options: { limit: 8192, name: 'images/[hash:8].[name].[ext]' } } ] } ] }, plugins: [ new webpack.DefinePlugin(checkHostContent), // 將處理好的 checkHostContent 放入 new webpack.HotModuleReplacementPlugin(), // 啓用熱替換模塊 new HtmlWebpackPlugin({ filename: 'index.html', // 生成的的html文件名 template: './src/index.html', // 被打包的html路徑 chunks: ['index'] // 須要引入的js,對應entry的key }), new ExtractTextPlugin({ // 單獨打包css filename: '[name].css' }) ] }
對比分析以下
{ module: { // module.loaders 改成 module.rules rules: [ // { // test: /\.(js|jsx)$/, // js-loader // loader: 'babel-loader?presets[]=es2015&presets[]=react' // } { test: /\.(js|jsx)$/, use: { loader: 'babel-loader', options: { // ? 後的參數能夠寫在這裏 presets: ['es2015', 'react'] } } }, // { // test: /\.less/, // less-loader // loaders: ExtractTextPlugin.extract('css-loader!less-loader') // } { test: /\.less$/, use: ExtractTextPlugin.extract({ use: [{ loader: "css-loader" }, { loader: "less-loader" }] }) }, // { // test: /\.(png|jpg|ttf)$/, // img-loader // loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' // } { test: /\.(png|jpg|ttf)$/, use: [ { loader: 'url-loader', options: { limit: 8192, name: 'images/[hash:8].[name].[ext]' } } ] } ] } }