React | 使用webpack構建React項目
配置React項目,需要完成的工作:
- 編譯jsx,es6,scss等資源
- 自動引入靜態資源到html頁面
- 實時編譯和刷新瀏覽器
- 按指定模塊化規範自動包裝模塊
- 自動給css添加瀏覽器內核前綴
- 按需打包合併js、css
根據webpack文檔編寫最基本的webpack配置,直接使用node api的方式
/* webpack.config.js */var webpack = require(webpack);// 輔助函數var utils = require(./utils);var fullPath = utils.fullPath;var pickFiles = utils.pickFiles;// 項目根路徑var ROOT_PATH = fullPath(../);// 項目源碼路徑var SRC_PATH = ROOT_PATH + /src;// 產出路徑var DIST_PATH = ROOT_PATH + /dist;// 是否是開發環境var __DEV__ = process.env.NODE_ENV !== production;// confvar alias = pickFiles({ id: /(conf/[^/]+).js$/, pattern: SRC_PATH + /conf/*.js});// componentsalias = Object.assign(alias, pickFiles({ id: /(components/[^/]+)/, pattern: SRC_PATH + /components/*/index.js}));// reducersalias = Object.assign(alias, pickFiles({ id: /(reducers/[^/]+).js/, pattern: SRC_PATH + /js/reducers/*}));// actionsalias = Object.assign(alias, pickFiles({ id: /(actions/[^/]+).js/, pattern: SRC_PATH + /js/actions/*}));var config = { context: SRC_PATH, entry: { app: [./pages/app.js] }, output: { path: DIST_PATH, filename: js/bundle.js }, module: {}, resolve: { alias: alias }, plugins: [ new webpack.DefinePlugin({ // http://stackoverflow.com/questions/30030031/passing-environment-dependent-variables-in-webpack "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || development) }) ]};module.exports = config;
/* webpack.dev.js */var webpack = require(webpack);var WebpackDevServer = require(webpack-dev-server);var config = require(./webpack.config);var utils = require(./utils);var PORT = 8080;var HOST = utils.getIP();var args = process.argv;var hot = args.indexOf(--hot) > -1;var deploy = args.indexOf(--deploy) > -1;// 本地環境靜態資源路徑var localPublicPath = http:// + HOST + : + PORT + /;config.output.publicPath = localPublicPath;config.entry.app.unshift(webpack-dev-server/client? + localPublicPath);new WebpackDevServer(webpack(config), { hot: hot, inline: true, compress: true, stats: { chunks: false, children: false, colors: true }, // Set this as true if you want to access dev server from arbitrary url. // This is handy if you are using a html5 router. historyApiFallback: true,}).listen(PORT, HOST, function() { console.log(localPublicPath);});
編譯jsx、es6、scss等資源:
● 使用 bael 和 babel-loader 編譯 jsx、es6
● 安裝插件: babel-preset-es2015 用於解析 es6
● 安裝插件:babel-preset-react 用於解析 jsx
// 首先需要安裝babel
$ npm i babel-core
// 安裝插件
$ npm i babel-preset-es2015babel-preset-react
// 安裝loader
$ npm i babel-loader
在項目根目錄創建 .babelrc 文件:
{ "presets": ["es2015", "react"]}
在 webpack.config.js 里添加:
// 使用緩存var CACHE_PATH = ROOT_PATH + /cache;// loadersconfig.module.loaders = [];// 使用 babel 編譯 jsx、es6config.module.loaders.push({ test: /.js$/, exclude: /node_modules/, include: SRC_PATH, // 這裡使用 loaders ,因為後面還需要添加 loader loaders: [babel?cacheDirectory= + CACHE_PATH]});
接下來使用 sass-loader 編譯 sass:
$ npm i sass-loader node-sasscss-loader style-loader
●css-loader 用於將 css 當做模塊一樣來 import
●style-loader 用於自動將 css 添加到頁面
在 webpack.config.js 里添加:
// 編譯 sassconfig.module.loaders.push({ test: /.(scss|css)$/, loaders: [style, css, sass]});
自動引入靜態資源到相應 html 頁面
● 使用 html-webpack-plugin
$ npm i html-webpack-plugin
在 webpack.config.js 里添加:
// html 頁面var HtmlwebpackPlugin = require(html-webpack-plugin);config.plugins.push( new HtmlwebpackPlugin({ filename: index.html, chunks: [app], template: SRC_PATH + /pages/app.html }));
打包合併 js、css
webpack 默認將所有模塊都打包成一個 bundle,並提供了 Code Splitting 功能便於我們按需拆分。在這個例子里我們把框架和庫都拆分出來:
在 webpack.config.js 添加:
config.entry.lib = [ react, react-dom, react-router, redux, react-redux, redux-thunk]
config.output.filename = js/[name].js;config.plugins.push( new webpack.optimize.CommonsChunkPlugin(lib, js/lib.js));
// 別忘了將 lib 添加到 html 頁面// chunks: [app, lib]
-END-
推薦閱讀:
※React源碼分析 - 組件更新與事務
※推薦幾個常用的小工具
※看別人吵架對你來說應該是好事兒
※Vue 性能優化
※React源碼分析 - 組件初次渲染
TAG:前端開發 |