基于webpack3.x从0开始搭建React开发环境
在開發react單頁面的時候無可避免的要使用到webpack打包,今天就從零開始搭建一個react的開發環境。
需要實現的功能有:
一、完成基本的目錄結構與基本打包
新建一個reactWebpack文件夾,進入該文件夾并執行 npm init 初始化一個項目(生成package.json文件),新建如下目錄結構:
reactWebpack -- dist(打包后文件) -- src(業務源碼) |-- index.html|-- app.js -- webpack.config.js(webpack配置文件) -- .babelrc(babel配置文件) -- package.json在reactWebpack文件夾下安裝以下依賴:
npm install -D webpack@3.11.0
如果全局環境下沒有webpack那么建議也全局安裝
npm install -g webpack@3.11.0
修改webpack的配置文件 webpack.config.js ,如下:
var path = require('path');module.exports = {entry: './src/index.js',output: {path: path.resolve(__dirname, 'dist'), // 這里需要絕對路徑filename: '[name].js'} }到這一步就可以使用webpack打包項目中依賴的js了,但是使用jsx和目前瀏覽器還不能完美支持的ES6語法還需要轉譯,將ES6等新的特性和jsx轉換成ES5語法讓瀏覽器不支持的特性得以支持。
安裝依賴 npm install babel-core babel-loader babel-preset-react babel-preset-2015
修改webpck.config.js加上對js文件處理的loader部分:
var path = require('path');module.exports = {entry: './src/index.js',output: {path: path.resolve(__dirname, 'dist'),filename: '[name].js'},module: {rules: [{test: /\.js|\.jsx$/, use: ['babel-loader'], exclude: path.resolve(__dirname, 'node_modules')}]} }修改babel配置文件.babelrc文件
{"presets": ["es2015", "react"] }配置打包html模板,先安裝依賴:
npm install -D html-webpack-plugin
修改webpack.config.js文件如下
var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {entry: './src/index.js',output: {path: path.resolve(__dirname, 'dist'),filename: '[name].js'},module: {rules: [{test: /\.js$/, use: 'babel-loader', exclude: path.resolve(__dirname, 'node_modules/')} ]},plugins: [new HtmlWebpackPlugin({template: './src/index.html',filename: 'index.html',inject: true})] }安裝項目依賴react等:
npm install --save react react-dom react-router-dom
修改index.html和app.js文件
index.html 如下:
<!DOCTYPE html> <html> <head><meta charset="utf-8" /><title></title> </head> <body> <div id="container"></div> </body> </html>app.js 如下:
import ReactDOM from 'react-dom' import React from 'react'ReactDOM.render(<div>我是組建</div>, document.getElementById('container'))到這里基本的目錄結構已經搭建完成,并且可以在根目錄下執行webpack進行打包。打包完成后在dist文件夾下會有index.html和app.js文件。
二、配置webpack熱加載
安裝如下依賴:
npm install -D webpack-dev-server@2.7.1
注意:是2.7.1版本
在根目錄下添加 dev.conf.js 文件:
var webpack = require('webpack') var WebpackDevServer = require('webpack-dev-server')var config = require('./webpack.config.js') var port = '8899' var host = 'localhost' var options = {contentBase: './dist',hot: true,host: host,port: port // 這里最好加上port }WebpackDevServer.addDevServerEntrypoints(config, options) var compiler = webpack(config) var server = new WebpackDevServer(compiler, options)server.listen(port, function(){console.log(host + ':' + port + '啟動成功') })修改webpack.config.js文件,添加了兩個插件:
var path = require('path') var webpack = require('webpack') var HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = {entry: './src/app.js',output: {path: path.resolve(__dirname, 'dist'),filename: '[name].js'},devtool: 'inline-source-map', // 生成map映射,方便定位錯誤module: {rules: [{test: /\.js$/, loader: 'babel-loader' }]},plugins: [ new webpack.NamedModulesPlugin(), // 新加new webpack.HotModuleReplacementPlugin(), // 新加new HtmlWebpackPlugin({template: './src/index.html',path: path.resolve(__dirname, 'dist'),chunks: ['main']})] }到這里開發環境配置完成,在根目錄下運行 node dev.conf.js 即可啟動一個開發服務器。
三、調整目錄結構
在上面已經完成可webpak開發環境的配置,下面要配置打包環境。在開始配置打包環境之前需要調整一下目錄的結構。因為在開發環境(dev)和打包(build)上線的環境有一部分不同,但是基礎部分又是相同的,所以需要合理的計劃一下。
主要分為三個配置文件 dev.conf.js(原webpack.config.js一部分內容)、build.conf.js和base.conf.js(原大部分webpack.config.js內容),這三個文件會被放在新建的build文件夾下。
調整后的文件目錄如下:
reactWebpack--build|--base.conf.js|--dev.conf.js|--build.conf.js-- dist(打包后文件)-- src(業務源碼)|-- index.html|-- app.js-- .babelrc(babel配置文件)-- package.json修改base.conf.js文件如下:
var path = require('path') var webpack = require('webpack') var HtmlWebpackPlugin = require('html-webpack-plugin')function resolve(dir){return path.resolve(__dirname, '../', dir) }module.exports = {entry: './src/app.js',output: {path: resolve('dist'),filename: '[name].js'},devtool: 'inline-source-map',module: {rules: [{test: /\.js$/, loader: 'babel-loader',exclude: resolve('node_modules')}]},plugins: [ new HtmlWebpackPlugin({template: './src/index.html',path: resolve('dist'),chunks: ['main']})] }安裝依賴 npm install -D webpack-merge并修改dev.conf.js文件如下:
var webpack = require('webpack') var WebpackDevServer = require('webpack-dev-server') var merge = require('webpack-merge')// 開發環境配置,這部分配置在打包的時候是不需要的 var webpackDevConfig = {plugins: [new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin()] }// 下面是服務器配置 var config = merge(webpackDevConfig, require('./base.conf.js')) var options = {contentBase: '../dist',hot: true,host: 'localhost' } var port = '8899'WebpackDevServer.addDevServerEntrypoints(config, options) var compiler = webpack(config) var server = new WebpackDevServer(compiler, options)server.listen(port, function(){console.log('啟動成功') })上面的目錄結構已經調整完成,在根目錄下運行 node build/dev.conf.js 即可開啟開發服務器。
四、配置完善的webpack打包部分
webpack是按照依賴打包的,但是如果不處理的話所有的依賴會被打包到一個文件中,也就是說無論是第三方依賴,還是自己寫的業務邏輯都會在同一個打包好的文件(main.js)中。
這會有很多問題,例如:
- 不方便客戶端緩存,客戶端肯定會緩存main.js,但是如果我們修改了業務代碼然后打包上線,這個main.js名稱沒有改變,而內容卻是修改了,并且客戶端緩存了main.js所以不一定會去獲取新的main.js,這樣就導致了新的代碼并沒有及時的被使用
- 沒有將第三方代碼和業務代碼分離,分離后第三方代碼是可以讓客戶端緩存以節省加載時間,因為我們修改的是自己的業務代碼
上面的配置還沒有去除注釋、警告和壓縮代碼以減小代碼體積
- 壓縮代碼JS代碼
修改build.conf.js文件如下:
var path = require('path') var webpack = require('webpack') var merge = require('webpack-merge') var baseConfig = require('./base.conf.js')var buildConfig = {plugins: [new webpack.DefinePlugin({'process.env': {'NODE_ENV': JSON.stringify('production')}}),new webpack.optimize.UglifyJsPlugin() // 新加] }module.exports = merge(buildConfig, baseConfig)在根目錄下執行webpack build/build.conf.js,即可看到打包出的文件會小很多。
提取第三方代碼單獨打包
修改代碼如下:
var path = require('path') var webpack = require('webpack') var merge = require('webpack-merge') var baseConfig = require('./base.conf.js')var buildConfig = {plugins: [new webpack.DefinePlugin({'process.env': {'NODE_ENV': JSON.stringify('production')}}),new webpack.optimize.CommonsChunkPlugin({name: 'vender', // 指定公共 bundle 的名稱minChunks: function (module, count) {console.log(count)return (module.resource &&/\.js$/.test(module.resource) &&module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0)}}),new webpack.optimize.CommonsChunkPlugin({name: 'manifest', // 提取webpack的運行時代碼chunks: ['vender']}),new webpack.optimize.UglifyJsPlugin()] }module.exports = merge(buildConfig, baseConfig)為文件名添加hash,當修改的時候文件名發生變化,讓客戶端及時獲取變化的文件,同時緩存沒有改變的文件。
修改base.conf.js文件如下:
var path = require('path') var webpack = require('webpack') var HtmlWebpackPlugin = require('html-webpack-plugin')function resolve(dir){return path.resolve(__dirname, '../', dir) }module.exports = {entry: './src/app.js',output: {path: resolve('dist'),filename: '[name]-[chunkHash].js' // 新加 chunkHash內容改變的時候chunkHash才會改變},devtool: 'inline-source-map',module: {rules: [{test: /\.js$/, loader: 'babel-loader',exclude: resolve('node_modules')}]},plugins: [ new HtmlWebpackPlugin({template: './src/index.html',path: resolve('dist'),chunks: ['main']})] }因為加上了chunkHash新生成的文件不會覆蓋老文件,那么就會產生很多文件,并不能立馬找到目標文件。這時可以考慮先清空打包的目標文件夾dist
安裝 npm install -D clean-webpack-plugin
修改 build/build.conf.js文件如下
var path = require('path') var webpack = require('webpack') var merge = require('webpack-merge') var baseConfig = require('./base.conf.js') var Clean = require('clean-webpack-plugin')var buildConfig = {plugins: [new webpack.DefinePlugin({'process.env': {'NODE_ENV': JSON.stringify('production')}}),new webpack.optimize.CommonsChunkPlugin({name: 'vender', // 指定公共 bundle 的名稱minChunks: function (module, count) {console.log(count)return (module.resource &&/\.js$/.test(module.resource) &&module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0)}}),new webpack.optimize.CommonsChunkPlugin({name: 'manifest',chunks: ['vender']}),new webpack.optimize.UglifyJsPlugin(),new Clean(['dist']) // 新加] }module.exports = merge(buildConfig, baseConfig)待續。。。。。。。。。。。。。。。。。。。。。。。。。。。
后續:1.CSS預處理器和后處理器的編譯 2. 圖片的加載 5. 跨域代理的配置 6. 依據react-router做代碼分割
參考:
? webpack中文文檔
? vue-cli生成的webpack配置文件
總結
以上是生活随笔為你收集整理的基于webpack3.x从0开始搭建React开发环境的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery中的ready
- 下一篇: TS引用JS模块