赞
踩
在开发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文件。
安装如下依赖:
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是按照依赖打包的,但是如果不处理的话所有的依赖会被打包到一个文件中,也就是说无论是第三方依赖,还是自己写的业务逻辑都会在同一个打包好的文件(main.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做代码分割
参考:
vue-cli生成的webpack配置文件
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。