vue-cli的webpack配置,迁移适用到react开发配置webpack

最近搞vue,用的vue-cli,快速构建开发环境,当然核心还是集成的webpack。之前自己做react的webpack环境配置总觉得差强人意,于是就把vue-cli的迁移过来,感觉还是不错的。对应一般开发需要,下面需要修改的就在build和config目录下的几个文件中




从webpack.base.conf.js 文件开始,无论生产环境还是开发环境都以这个为基础的,

module.exports = {
	entry: {
		app: ['./src/js/index.js'],//入口文件
		babel: ['babel-polyfill'] //babel-polyfill 和redux 单独打包减小app.js 的打包体积 用于配合externals
		redux: ['redux','react-redux'],},output: {
		path: config.build.assetsRoot,filename: '[name].js',publicPath: process.env.NODE_ENV === 'production'
			? config.build.assetsPublicPath
			: config.dev.assetsPublicPath,libraryTarget: 'umd'	//用于外部引入的 react.js 等
	},resolve: {
		extensions: ['.js','.json'],symlinks: false
	},module: {
		rules: [
			{
				test: /\.js$/,loader: 'babel-loader',include: [resolve('src'),resolve('test')],exclude:[resolve('node_modules')],//在node_modules的文件不被babel理会
				query: {
                    presets: ['react','stage-2']
                }
			},{
				test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,loader: 'url-loader',options: {
					limit: 10000,name: utils.assetsPath('img/[name].[hash:7].[ext]'),}
			},{
				test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,name: utils.assetsPath('media/[name].[hash:7].[ext]')
				}
			},{
				test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
				}
			},// {
            //     test: /\.less$/,//     use: ExtractTextPlugin.extract({ use: extractCssLoaders,fallback: 'style-loader' }),// }
		]
	},// 配置全局使用
	plugins: [
		new webpack.ProvidePlugin({
			"React": "react","ReactDOM": "react-dom","_": "lodash","classnames":"classnames"
		}),//extract css into its own file
		new ExtractTextPlugin({
			filename: utils.assetsPath('css/[name].[contenthash].css')
		}),],// 单独提取出 react 减小打包文件大小
	externals: {
        'react-router': {
            amd: 'react-router',root: 'ReactRouter',commonjs: 'react-router',commonjs2: 'react-router'
        },react: {
            amd: 'react',root: 'React',commonjs: 'react',commonjs2: 'react'
        },'react-dom': {
            amd: 'react-dom',root: 'ReactDOM',commonjs: 'react-dom',commonjs2: 'react-dom'
        }
    }
}

然后再 util.js 文件里,主要就在cssLoaders

exports.cssLoaders = function (options) {
	options = options || {}

	var cssLoader = {
		loader: 'css-loader',options: {
			minimize: process.env.NODE_ENV === 'production',sourceMap: options.sourceMap,modules: true,localIdentName: '[local]--[hash:base64:6]',//class 名字 代替
		}
	}

	// generate loader string to be used with extract text plugin
	function generateLoaders(loader,loaderOptions) {
		var loaders = [cssLoader];
		if (loader) {
			loaders.push({
				loader: loader + '-loader',options: Object.assign({},loaderOptions,{
					sourceMap: options.sourceMap
				})
			})
		}

		// Extract CSS when that option is specified
		//(which is the case during production build)
		if (options.extract) {
			return ExtractTextPlugin.extract({
				use: loaders,publicPath: '../../',//解决 build css bg img 加载路径不对问题
			    fallback: 'react-style-loader' // 修改vue-style-loader
			})
		} else {
			return ['react-style-loader'].concat(loaders)
		}
	}

	// https://vue-loader.vuejs.org/en/configurations/extract-css.html
	return {
		css: generateLoaders(),postcss: generateLoaders(),less: generateLoaders('less'),sass: generateLoaders('sass',{ indentedSyntax: true }),scss: generateLoaders('sass'),stylus: generateLoaders('stylus'),styl: generateLoaders('stylus')
	}
}

webpack.prod.conf 生产环境的修改,打包时,redux,和babel-polyfill 分离打包配置 配合 webpack.base.conf.js中entry修改

new webpack.optimize.CommonsChunkPlugin({
			name:  ['app','redux','babel'],//单独提取打包
			filename: './static/js/[name].js',minChunks: ({resource}) => {
				resource &&
				/\.js$/.test(resource) &&
				resource.indexOf(
					path.join(__dirname,'../node_modules')
				) === 0
			}   
		}),// extract webpack runtime and module manifest to its own file in order to
		// prevent vendor hash from being updated whenever app bundle is updated
		new webpack.optimize.CommonsChunkPlugin({
			name: 'manifest',chunks: ['app','babel']
		}),

webpack.dev.conf.js和webpack.prod.conf.js 有同一个地方修要, 用于在inde.html上写入外部js


new HtmlWebpackPlugin({
			title: config.title,filename: 'index.html',template: 'index.ejs',//修改模板类型 为ejs
			inject: true,js: config.externalsJs_dev	// 开发环境是config.externalsJs_prod
		}),

当然config.externalsJs_dev 配置到了config/index.js 中

	// 提取出的文件链接
	externalsJs_dev:[
		'https://cdn.bootcss.com/react/16.0.0/umd/react.development.js','https://cdn.bootcss.com/react-dom/16.0.0/umd/react-dom.development.js','https://cdn.bootcss.com/react-router/4.2.0/react-router.js'
	],externalsJs_prod: [
		'https://cdn.bootcss.com/react/16.0.0/umd/react.production.min.js','https://cdn.bootcss.com/react-dom/16.0.0/umd/react-dom.production.min.js','https://cdn.bootcss.com/react-router/4.2.0/react-router.min.js'
	],title: 'react-redux-demo' //模板标题
删除项目 根目录下的index.html 改为index.ejs, 内容如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
    <div id="root"></div>
    <% for (var i = 0,item; item = htmlWebpackPlugin.options.js[i++];) { %>
        <script type="text/javascript" src="<%= item %>"></script>
    <% } %>
</body>
</html>
目录结构如下 包括打包

运行一下npm run build --report=true 看看打包分析, 暂时未集成babel-runtime


是否要集成babel-runtime 需要修改.babelrc 文件中

"plugins": ["transform-runtime"],
取消此行的注释, 打包分析如下


package.json 内容 整个修改后的依赖

{
  "name": "wz","version": "1.0.0","description": "","main": "index.js","scripts": {
    "dev": "node build/dev-server.js","start": "node build/dev-server.js","build": "node build/build.js"
  },"author": "","license": "ISC","dependencies": {
    "cross-env": "^5.0.5","expect": "^1.20.1","node-libs-browser": "^2.0.0","node-sass": "^4.5.3","npm": "^5.3.0","react": "^15.6.1","react-addons-test-utils": "^15.1.0","react-dom": "^15.6.1","react-redux": "^5.0.4","redux": "^3.5.2","redux-logger": "^3.0.1","redux-promise": "^0.5.3","redux-thunk": "^2.1.0","shelljs": "^0.7.8","style-loader": "^0.18.2"
  },"devDependencies": {
    "autoprefixer": "^7.1.2","babel-core": "^6.10.4","babel-loader": "^7.1.2","babel-plugin-react-transform": "^2.0.2","babel-plugin-transform-runtime": "^6.23.0","babel-polyfill": "^6.9.1","babel-preset-env": "^1.3.2","babel-preset-react": "^6.11.1","babel-preset-stage-0": "^6.5.0","babel-preset-stage-2": "^6.22.0","babel-register": "^6.9.0","bower-webpack-plugin": "^0.1.9","chalk": "^2.0.1","chromedriver": "^2.27.2","compression-webpack-plugin": "^1.0.0","connect-history-api-fallback": "^1.3.0","copy-webpack-plugin": "^4.1.1","core-js": "^2.0.0","cross-spawn": "^5.0.1","css-loader": "^0.28.5","cssnano": "^3.10.0","eventsource-polyfill": "^0.9.6","express": "^4.14.1","extract-text-webpack-plugin": "^3.0.1","file-loader": "^1.1.5","friendly-errors-webpack-plugin": "^1.6.1","html-webpack-plugin": "^2.29.0","http-proxy-middleware": "^0.17.3","less": "^2.7.2","less-loader": "^4.0.3","minimist": "^1.2.0","open": "0.0.5","opn": "^5.1.0","optimize-css-assets-webpack-plugin": "^3.0.0","ora": "^1.3.0","postcss-import": "^10.0.0","postcss-loader": "^2.0.6","precss": "^2.0.0","react-style-loader": "^1.0.1","react-transform-hmr": "^1.0.4","rimraf": "^2.6.0","url-loader": "^0.6.2","webpack": "^3.5.5","webpack-bundle-analyzer": "^2.9.0","webpack-dev-middleware": "^1.6.1","webpack-dev-server": "^2.4.4","webpack-hot-middleware": "^2.11.0","webpack-merge": "^4.1.0"
  },"engines": {
    "node": ">= 4.0.0","npm": ">= 3.0.0"
  }
}


以上可能有不准确的或者冗余地方 请酌情参考

相关文章

react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接...
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc ...