16個demo,webpack+react搭配使用javascript
首先教你們2個新技能css
1.按照正常github地址狀況下,你的github自己不能訪問目錄。html
例如要訪問vue-demo下的vueCpu文件夾:https://github.com/holidaying...(顯示404)可是在目錄上加上tree/master/:https://github.com/holidaying... (master是分支名)就能夠訪問。前端
2.github目錄的製做vue
明確一個問題。一個標題就是一個目錄名稱java
寫法[xx](#題目名稱)#不能少node
題目名稱的寫法規則:abc demo-> abc-demo,Abc-Demo->abc-demo。會忽略:和()即就是題目中全部可見字符的空格均用-鏈接,中、英文空格要分開,中文空格對應中文-。而且全爲小寫react
首先,install Webpack 和 webpack-dev-server.jquery
$ npm i -g webpack webpack-dev-server
# Linux & Mac $ git clone git@github.com:holidaying/webpack-demo.git # Windows $ git clone https://github.com/holidaying/webpack-demo.git : $ cd webpack-demos $ npm install
接下來就能夠進行demo演示了.webpack
$ cd demo01 $ webpack-dev-server
用瀏覽器訪問 http://127.0.0.1:8080.
Webpack 是前端的打包工具類相似於 Grunt and Gulp.可是有區別,由於它是模塊化構建機制,Webpack能夠看作是模塊打包機:它作的事情是,分析你的項目結構,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),並將其打包爲合適的格式以供瀏覽器使用。WebPack和Grunt以及Gulp相比有什麼特性
其實Webpack和另外兩個並無太多的可比性,Gulp/Grunt是一種可以優化前端的開發流程的工具,而WebPack是一種模塊化的解決方案,不過Webpack的優勢使得Webpack能夠替代Gulp/Grunt類的工具。
Grunt和Gulp的工做方式是:在一個配置文件中,指明對某些文件進行相似編譯,組合,壓縮等任務的具體步驟,這個工具以後能夠自動替你完成這些任務。
更多信息.
$ webpack main.js bundle.js
它的配置文件是 webpack.config.js
.
// webpack.config.js module.exports = { entry: './main.js', output: { filename: 'bundle.js' } };
有了webpack.config.js
,你能夠不帶參數使用webpack
$ webpack
一些命令行選項你應該知道。
webpack
– 構建文件
webpack -p
– 發佈
webpack --watch
– 監聽項目
webpack -d
– 包含 source maps方便調試
webpack --colors
– 讓打包界面更好看
去構建你的項目, 你能夠把啓動項寫進package.json
// package.json { // ... "scripts": { "dev": "webpack-dev-server --devtool eval --progress --colors", "deploy": "NODE_ENV=production webpack -p" }, // ... }
Webpack會入口文件進行打包成bundle.js.
例子, main.js
是單文件入口.
// main.js document.write('<h1>Hello World</h1>');
index.html
<html> <body> <script type="text/javascript" src="bundle.js"></script> </body> </html>
Webpack follows webpack.config.js
to build bundle.js
.
// webpack.config.js module.exports = { entry: './main.js', output: { filename: 'bundle.js' } };
啓動服務, 訪問 http://127.0.0.1:8080 .
$ webpack-dev-server
多個入口文件,實用於多個頁面的應用
// main1.js document.write('<h1>Hello World</h1>'); // main2.js document.write('<h2>Hello Webpack</h2>');
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' } };
經過使用不一樣的loader,webpack經過調用外部的腳本或工具能夠對各類各樣的格式的文件進行處理(更多信息). 例如, Babel-loader Babel實際上是一個編譯JavaScript的平臺能夠將 JSX/ES6 文件轉換成瀏覽器能夠識別的js文件. 官方文檔loaders.
main.jsx
is a JSX 文件.
const React = require('react'); const ReactDOM = require('react-dom'); ReactDOM.render( <h1>Hello, world!</h1>, document.querySelector('#wrapper') );
index.html
<html> <body> <div id="wrapper"></div> <script src="bundle.js"></script> </body> </html>
webpack.config.js
module.exports = { entry: './main.jsx', output: { filename: 'bundle.js' }, module: { loaders:[ { test: /\.js[x]?$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react' }, ] } };
在 webpack.config.js
, module.loaders
區域是用來分配loader的. 像上面的代碼片斷使用了 babel-loader
須要安裝插件 babel-preset-es2015 和 babel-preset-react to 編譯成 ES6 and React. 能夠用query配置參數
module: { loaders: [ { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: { presets: ['es2015', 'react'] } } ] }
Webpack 容許你在js文件中require CSS , 經過 CSS-loader來預處理css文件.
main.js
require('./app.css');
app.css
body { background-color: blue; }
index.html
<html> <head> <script type="text/javascript" src="bundle.js"></script> </head> <body> <h1>Hello World</h1> </body> </html>
webpack.config.js
module.exports = { entry: './main.js', output: { filename: 'bundle.js' }, module: { loaders:[ { test: /\.css$/, loader: 'style-loader!css-loader' }, ] } };
可是,你須要使用2中loaders來轉換CSS 文件. 第一個是 CSS-loader 來讀取CSS文件, 另一個是Style-loader 是將style樣式插入到html中。 中間用!鏈接
啓動服務後, index.html
有內部樣式.
<head> <script type="text/javascript" src="bundle.js"></script> <style type="text/css"> body { background-color: blue; } </style> </head>
Webpack 容許你在js文件中require圖片 , 經過 url-loader和file-loader來預處理圖片文件.
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 bytes,它將會轉成base64位的地址; 相反, 它就是普通地址.
參數前是用?鏈接的
啓動服務後, small.png
and big.png
將會有一下的地址.
<img src="data:image/png;base64,iVBOR...uQmCC"> <img src="4853ca667a2b8b8844eb2693ac1b2578.png">
css-loader?modules
(the query parameter modules) enables the CSS Modules spec.
CSS Module能夠開啓全局變量和局部變量,:global(...)表示全局變量,能夠在全局中使用樣式(更多信息)
index.html
<html> <body> <h1 class="h1">Hello World</h1> <h2 class="h2">Hello Webpack</h2> <div id="example"></div> <script src="./bundle.js"></script> </body> </html>
app.css
.h1 { color:red; } :global(.h2) { color: blue; }
main.jsx
var React = require('react'); var ReactDOM = require('react-dom'); var style = require('./app.css'); ReactDOM.render( <div> <h1 className={style.h1}>Hello World</h1> <h2 className="h2">Hello Webpack</h2> </div>, document.getElementById('example') );
webpack.config.js
module.exports = { entry: './main.jsx', output: { filename: 'bundle.js' }, module: { loaders:[ { test: /\.js[x]?$/, exclude: /node_modules/, loader: 'babel-loader', query: { presets: ['es2015', 'react'] } }, { test: /\.css$/, loader: 'style-loader!css-loader?modules' } ] } };
啓動服務.
$ webpack-dev-server
訪問 http://127.0.0.1:8080 , 你將看到只有第二個 h1
是紅的,由於它是局部, 同時 h2
是藍色的, 由於是h2
全局的.
Webpack 能夠去掉自己附加的東西,優化代碼 UglifyJs Plugin will minify output(bundle.js
) JS codes.
main.js
var longVariableName = 'Hello'; longVariableName += ' World'; document.write('<h1>' + longVariableName + '</h1>');
index.html
<html> <body> <script src="bundle.js"></script> </body> </html>
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 } }) ] };
啓動服務後, main.js
將會壓縮以下.
var o="Hello";o+=" World",document.write("<h1>"+o+"</h1>")
這個例子須要加載三個插件
html-webpack-plugin 建立 index.html
,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' }) ] };
啓動 webpack-dev-server
.啓動這個須要node7版本以上
$ webpack-dev-server
不用手寫index.html
也不用手動打開瀏覽器 Webpack 能夠爲你作這些事.
你能夠利用環境變量來控制特定代碼的輸出
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] };
# Linux & Mac $ env DEBUG=true webpack-dev-server # Windows $ set DEBUG=true $ webpack-dev-server
對於大型項目,把全部代碼編譯到一個文件並非有效的, Webpack 容許你把代碼分紅好多塊. 特別是某種狀況下,只須要個別代碼這些塊能夠按需加載。
在commonjs中有一個Modules/Async/A規範,裏面定義了require.ensure語法。webpack實現了它,做用是能夠在打包的時候進行代碼分片,並異步加載分片後的代碼。用法以下:
require.ensure([], function(require){ var list = require('./list'); list.show(); });
此時list.js會被打包成一個單獨的chunk文件,大概長這樣:
1.fb874860b35831bc96a8.js
可讀性比較差。我在上一篇結尾也提到了,給它命名的方式,那就是給require.ensure傳遞第三個參數,如:
require.ensure([], function(require){ var list = require('./list'); list.show(); }, 'list');
這樣就能獲得你想要的文件名稱:
首先,你須要用 require.ensure
to 來定義一個分割的點. (官方文檔)
// main.js require.ensure(['./a'], function(require) { var content = require('./a'); document.open(); document.write('<h1>' + content + '</h1>'); document.close(); });
require.ensure
告訴 Webpack ./a.js
應該從 bundle.js
中分離成一個單獨的塊
// a.js module.exports = 'Hello World';
Now Webpack takes care of the dependencies, output files and runtime stuff. You don't have to put any redundancy into your index.html
and webpack.config.js
.
<html> <body> <script src="bundle.js"></script> </body> </html>
webpack.config.js
module.exports = { entry: './main.js', output: { filename: 'bundle.js' } };
啓動服務.
$ webpack-dev-server
在界面上, 你感受不到任何不同的地方. 可是, Webpack 已經把 main.js
和 a.js
編譯成(bundle.js
和 1.bundle.js
)的塊。
dem10是一種,另外一種是利用bundle-loader.
// main.js // Now a.js is requested, it will be bundled into another file var load = require('bundle-loader!./a.js'); // To wait until a.js is available (and get the exports) // you need to async wait for it. load(function(file) { document.open(); document.write('<h1>' + file + '</h1>'); document.close(); });
require('bundle-loader!./a.js')
tells Webpack to load a.js
from another chunk.
Now Webpack will build main.js
into bundle.js
, and a.js
into 1.bundle.js
.
利用webpack.optimize.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') ] }
利用webpack.optimize.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') ] };
If you want a module available as variable in every module, such as making $ and jQuery available in every module without writing require("jquery")
. You should use 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" }) ] };
插件會執行兩次這個方法,第一次將公共的第三方代碼抽離移到vendor的塊中,這個過程以前也講過會將運行時runtime也轉移到vendor塊中,第二次執行則是將運行時runtime抽離出來轉移到manifest塊中。這步操做解決了緩存問題。
這樣處理,最後會生成3個打包文件chunk,app.js是業務代碼,vendor則是公共的第三方代碼,manifest.js則是運行時。
webpack能夠不處理應用的某些依賴庫,使用externals配置後,依舊能夠在代碼中經過CMD、AMD或者window/global全局的方式訪問。若是你想引入一些全局變量, 可是不想被加載處理, 你能夠在 webpack.config.js
使用 externals
模塊 (官方文檔).
有時咱們但願咱們經過script引入的庫,如用CDN的方式引入的jquery,咱們在使用時,依舊用require的方式來使用,可是卻不但願webpack將它又編譯進文件中。
<script src="http://code.jquery.com/jquery...
例子, data.js
.
var data = 'Hello World';
We can expose data
as a global variable.
// webpack.config.js module.exports = { entry: './main.jsx', output: { filename: 'bundle.js' }, module: { loaders:[ { test: /\.js[x]?$/, exclude: /node_modules/, loader: 'babel-loader', query: { presets: ['es2015', 'react'] } }, ] }, externals: { // require('data') is external and available // on the global var data 'data': 'data' } };
如今, 你能夠require data
做爲模塊化引入進來使用. 可是其實是一個全局變量
// main.jsx var data = require('data'); var React = require('react'); var ReactDOM = require('react-dom'); ReactDOM.render( <h1>{data}</h1>, document.body );
Hot Module Replacement (HMR) exchanges, adds, or removes modules while an application is running without a page reload.
經過webpack-dev-server.你可使用2中方式 來進行熱模塊替換
(1) Specify --hot
and --inline
on the command line
$ webpack-dev-server --hot --inline
參數的意思:
--hot
: adds the HotModuleReplacementPlugin and switch the server to hot mode.
--inline
: embed the webpack-dev-server runtime into the bundle.
--hot --inline
: also adds the webpack/hot/dev-server entry.
(2) 修改 webpack.config.js
.
添加 new webpack.HotModuleReplacementPlugin()
to the plugins
模塊
添加 webpack/hot/dev-server
和 webpack-dev-server/client?http://localhost:8080
to the entry
模塊
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, '.') }] } };
啓動服務
$ webpack-dev-server
訪問 http://localhost:8080, 你能夠在瀏覽器上看到 'Hello World' .
不要關閉服務.打開終端找到 App.js
, 同時修改 'Hello World' 爲 'Hello Webpack'. 保存後,你就能夠在瀏覽器上看到數據更新了
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>
利用webpack作的例子 React-router's 官方例子.
Let's imagine a little app with a dashboard, inbox, and calendar.
+---------------------------------------------------------+ | +---------+ +-------+ +--------+ | | |Dashboard| | Inbox | |Calendar| Logged in as Jane | | +---------+ +-------+ +--------+ | +---------------------------------------------------------+ | | | Dashboard | | | | | | +---------------------+ +----------------------+ | | | | | | | | | + + | +---------> | | | | | | | | | | | | | + | | +-------------> | | | | | | + | | | | | | | | | | | | | | | | +-+---+----+-----+----+ +----------------------+ | | | +---------------------------------------------------------+
$ webpack-dev-server --history-api-fallback
webpack-howto, by Pete Hunt
Diving into Webpack, by Web Design Weekly
Webpack and React is awesome, by Christian Alfoni
Browserify vs Webpack, by Cory House
React Webpack cookbook, by Christian Alfoni
全文參考阮老師的教程。