webpack

什麼是Webpack?

事實上它是一個打包工具,而不是像RequireJS或SeaJS這樣的模塊加載器,經過使用Webpack,可以像Node.js同樣處理依賴關係,而後解析出模塊之間的依賴,將代碼打包javascript

安裝Webpack

首先得有Node.jscss

而後經過npm install -g webpack安裝webpack,固然也能夠經過gulp來處理webpack任務,若是使用gulp的話就npm install --save-dev gulp-webpackhtml

配置Webpack

Webpack的構建過程須要一個配置文件,一個典型的配置文件大概就是這樣java

var webpack = require('webpack'); var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js'); module.exports = { entry: { entry1: './entry/entry1.js', entry2: './entry/entry2.js' }, output: { path: __dirname, filename: '[name].entry.js' }, resolve: { extensions: ['', '.js', '.jsx'] }, module: { loaders: [{ test: /\.js$/, loader: 'babel-loader' }, { test: /\.jsx$/, loader: 'babel-loader!jsx-loader?harmony' }] }, plugins: [commonsPlugin] }; 

這裏對Webpack的打包行爲作了配置,主要分爲幾個部分:react

  • entry:指定打包的入口文件,每有一個鍵值對,就是一個入口文件
  • output:配置打包結果,path定義了輸出的文件夾,filename則定義了打包結果文件的名稱,filename裏面的[name]會由entry中的鍵(這裏是entry1和entry2)替換
  • resolve:定義瞭解析模塊路徑時的配置,經常使用的就是extensions,能夠用來指定模塊的後綴,這樣在引入模塊時就不須要寫後綴了,會自動補全
  • module:定義了對模塊的處理邏輯,這裏能夠用loaders定義了一系列的加載器,以及一些正則。當須要加載的文件匹配test的正則時,就會調用後面的loader對文件進行處理,這正是webpack強大的緣由。好比這裏定義了凡是.js結尾的文件都是用babel-loader作處理,而.jsx結尾的文件會先通過jsx-loader處理,而後通過babel-loader處理。固然這些loader也須要經過npm install安裝
  • plugins: 這裏定義了須要使用的插件,好比commonsPlugin在打包多個入口文件時會提取出公用的部分,生成common.js

固然Webpack還有不少其餘的配置,具體能夠參照它的配置文檔webpack

執行打包

若是經過npm install -g webpack方式安裝webpack的話,能夠經過命令行直接執行打包命令,好比這樣:git

$webpack --config webpack.config.js 

這樣就會讀取當前目錄下的webpack.config.js做爲配置文件執行打包操做程序員

若是是經過gulp插件gulp-webpack,則能夠在gulpfile中寫上gulp任務:es6

var gulp = require('gulp'); var webpack = require('gulp-webpack'); var webpackConfig = require('./webpack.config'); gulp.task("webpack", function() { return gulp .src('./') .pipe(webpack(webpackConfig)) .pipe(gulp.dest('./build')); }); 

組件編寫

使用Babel提高逼格

Webpack使得咱們可使用Node.js的CommonJS規範來編寫模塊,好比一個簡單的Hello world模塊,就能夠這麼處理:github

var React = require('react'); var HelloWorldComponent = React.createClass({ displayName: 'HelloWorldComponent', render: function() { return ( <div>Hello world</div> ); } }); module.exports = HelloWorldComponent; 

等等,這和以前的寫法沒啥差異啊,依舊沒有逼格...程序員敲碼要有geek範,要逼格than逼格,這太low了。如今都ES6了,React的代碼也要寫ES6,babel-loader就是幹這個的。Babel可以將ES6代碼轉換成ES5。首先須要經過命令npm install --save-dev babel-loader來進行安裝,安裝完成後就可使用了,一種使用方式是以前介紹的在webpack.config.js的loaders中配置,另外一種是直接在代碼中使用,好比:

var HelloWorldComponent = require('!babel!jsx!./HelloWorldComponent'); 

那咱們應當如何使用Babel提高代碼的逼格呢?改造一下以前的HelloWorld代碼吧:

import React from 'react'; export default class HelloWorldComponent extends React.Component { constructor() { super(); this.state = {}; } render() { return ( <div>Hello World</div> ); } } 

這樣在其餘組件中須要引入HelloWorldComponent組件,就只要就能夠了:

import HelloWorldComponent from './HelloWorldComponent' 

怎麼樣是否是更有逼格了?經過import引入模塊,還能夠直接定義類和類的繼承關係,這裏也再也不須要getInitialState了,直接在構造函數constructor中用this.state = xxx就行了

Babel帶來的固然還不止這些,在其幫助下還能嘗試不少優秀的ES6特性,好比箭頭函數,箭頭函數的特色就是內部的this和外部保持一致,今後能夠和that_this說再見了

['H', 'e', 'l', 'l', 'o'].map((c) => { return (<span>{c}</span>); }); 

其餘還有不少,具體能夠參照Babel的學習文檔

樣式編寫

我是一個強烈地Less依賴患者,脫離了Less直接寫CSS就會出現四肢乏力、不想幹活、心情煩躁等現象,並且還不喜歡在寫Less時候加前綴,日常都是gulp+less+autoprefixer直接處理的,那麼在Webpack組織的React組件中要怎麼寫呢?

沒錯,依舊是使用loader

能夠在webpack.config.js的loaders中增長Less的配置:

{
  test: /\.less$/, loader: 'style-loader!css-loader!autoprefixer-loader!less-loader' } 

經過這樣的配置,就能夠直接在模塊代碼中引入Less樣式了:

import React from 'react'; require('./HelloWorldComponent.less'); export default class HelloWorldComponent extends React.Component { constructor() { super(); this.state = {}; } render() { return ( <div>Hello World</div> ); } } 

其餘

Webpack的loader爲React組件化提供了不少幫助,像圖片也提供了相關的loader:

{ test: /\.png$/, loader: "url-loader?mimetype=image/png" } 

更多地loader能夠移步webpack的wiki

在Webpack下實時調試React組件

Webpack和React結合的另外一個強大的地方就是,在修改了組件源碼以後,不刷新頁面就能把修改同步到頁面上。這裏須要用到兩個庫webpack-dev-serverreact-hot-loader

首先須要安裝這兩個庫,npm install --save-dev webpack-dev-server react-hot-loader

安裝完成後,就要開始配置了,首先須要修改entry配置:

entry: {
  helloworld: [
    'webpack-dev-server/client?http://localhost:3000', 'webpack/hot/only-dev-server', './helloworld' ] }, 

經過這種方式指定資源熱啓動對應的服務器,而後須要配置react-hot-loader到loaders的配置當中,好比個人全部組件代碼所有放在scripts文件夾下:

{
  test: /\.js?$/, loaders: ['react-hot', 'babel'], include: [path.join(__dirname, 'scripts')] } 

最後配置一下plugins,加上熱替換的插件和防止報錯的插件:

plugins: [
  new webpack.HotModuleReplacementPlugin(), new webpack.NoErrorsPlugin() ] 

這樣配置就完成了,可是如今要調試須要啓動一個服務器,並且以前配置裏映射到http://localhost:3000,因此就在本地3000端口起個服務器吧,在項目根目錄下面建個server.js:

var webpack = require('webpack'); var WebpackDevServer = require('webpack-dev-server'); var config = require('./webpack.config'); new WebpackDevServer(webpack(config), { publicPath: config.output.publicPath, hot: true, historyApiFallback: true }).listen(3000, 'localhost', function (err, result) { if (err) console.log(err); console.log('Listening at localhost:3000'); }); 

這樣就能夠在本地3000端口開啓調試服務器了,好比個人頁面是根目錄下地index.html,就能夠直接經過http://localhost:3000/index.html訪問頁面,修改React組件後頁面也會被同步修改,這裏貌似使用了websocket來同步數據。圖是一個簡單的效果:

相關文章
相關標籤/搜索