webpack4 + react 搭建多页面应用示例
webpack升级到4之后还没好好的同步一个可实用的webpack架子,接下来用webpack4来搭建一个简单的react的多界面应用,废话不说直接撸码
创建工程
$mkdirdemo&&cddemo $npminit-y
webpack配置
安装react+babel依赖
$npmi-Sreact@16.3.0react-dom@16.3.0 $npmi-Dwebpack@4.4.1webpack-cli@2.0.13webpack-dev-server@3.1.1webpack-merge@4.1.2babel-cli@6.26.0babel-preset-env@1.6.1babel-preset-react@6.24.1babel-preset-react-hmre@1.1.1babel-loader@7.1.4file-loader@1.1.11url-loader@1.0.1
webpack.base.conf.js(config->webpack)
constentry=require("./webpack.entry.conf");
constnewEntry={};
for(letnameinentry){
newEntry[name]=entry[name][0]
}
letconfig={
entry:newEntry,
resolve:{
extensions:[".js",".json",".jsx",".css",".pcss"],
}
};
module.exports=config;
webpack.dev.conf.js
constwebpack=require('webpack');//引入webpack
constopn=require('opn');//打开浏览器
constmerge=require('webpack-merge');//webpack配置文件合并
constpath=require("path");
constbaseWebpackConfig=require("./webpack.base.conf");//基础配置
constwebpackFile=require("./webpack.file.conf");//一些路径配置
consteslintFormatter=require('react-dev-utils/eslintFormatter');
letconfig=merge(baseWebpackConfig,{
/*设置开发环境*/
mode:'development',
output:{
path:path.resolve(webpackFile.devDirectory),
filename:'js/[name].js',
chunkFilename:"js/[name].js",
publicPath:''
},
optimization:{
runtimeChunk:{
name:'manifest'
},
//包拆分
splitChunks:{
cacheGroups:{
common:{//项目的公共组件
chunks:"initial",
name:"common",
minChunks:2,
maxInitialRequests:5,
minSize:0
},
vendor:{//第三方组件
test:/node_modules/,
chunks:"initial",
name:"vendor",
priority:10,
enforce:true
}
}
}
},
plugins:[
/*设置热更新*/
newwebpack.HotModuleReplacementPlugin(),
],
module:{
rules:[
{
test:/\.(js|jsx)$/,
use:[
'babel-loader',
'cache-loader',
],
include:[
path.resolve(__dirname,"../../app"),
path.resolve(__dirname,"../../entryBuild")
],
exclude:[
path.resolve(__dirname,"../../node_modules")
],
},
{
test:/\.(css|pcss)$/,
loader:'style-loader?sourceMap!css-loader?sourceMap!postcss-loader?sourceMap',
exclude:/node_modules/
},
{
test:/\.(png|jpg|gif|ttf|eot|woff|woff2|svg|swf)$/,
loader:'file-loader?name=[name].[ext]&outputPath='+webpackFile.resource+'/'
},
{
test:/\.(js|jsx)$/,
enforce:'pre',
use:[
{
options:{
formatter:eslintFormatter,
eslintPath:require.resolve('eslint'),
//@remove-on-eject-begin
baseConfig:{
extends:[require.resolve('eslint-config-react-app')],
},
//ignore:false,
useEslintrc:false,
//@remove-on-eject-end
},
loader:require.resolve('eslint-loader'),
},
],
include:[
path.resolve(__dirname,"../../app")
],
exclude:[
path.resolve(__dirname,"../../node_modules")
],
}
]
},
/*设置api转发*/
devServer:{
host:'0.0.0.0',
port:8080,
hot:true,
inline:true,
contentBase:path.resolve(webpackFile.devDirectory),
historyApiFallback:true,
disableHostCheck:true,
proxy:[
{
context:['/api/**','/u/**'],
target:'http://10.8.200.69:8080/',
secure:false
}
],
/*打开浏览器并打开本项目网址*/
after(){
opn('http://localhost:'+this.port);
}
}
});
module.exports=config;
webpack.prod.conf.js
constpath=require('path');
constmerge=require('webpack-merge');
constHtmlWebpackPlugin=require('html-webpack-plugin');
constCopyWebpackPlugin=require('copy-webpack-plugin');
constCleanWebpackPlugin=require('clean-webpack-plugin');
constOptimizeCSSPlugin=require('optimize-css-assets-webpack-plugin');
constExtractTextPlugin=require("extract-text-webpack-plugin");
constbaseWebpackConfig=require("./webpack.base.conf");
constwebpackFile=require('./webpack.file.conf');
constentry=require("./webpack.entry.conf");
constwebpackCom=require("./webpack.com.conf");
letconfig=merge(baseWebpackConfig,{
/*设置生产环境*/
mode:'production',
output:{
path:path.resolve(webpackFile.proDirectory),
filename:'js/[name].[chunkhash:8].js',
chunkFilename:"js/[name]-[id].[chunkhash:8].js",
},
optimization:{
//包清单
runtimeChunk:{
name:"manifest"
},
//拆分公共包
splitChunks:{
cacheGroups:{
common:{//项目公共组件
chunks:"initial",
name:"common",
minChunks:2,
maxInitialRequests:5,
minSize:0
},
vendor:{//第三方组件
test:/node_modules/,
chunks:"initial",
name:"vendor",
priority:10,
enforce:true
}
}
}
},
plugins:[
//extractcssintoitsownfile
newExtractTextPlugin('css/[name].[md5:contenthash:hex:8].css'),
//CompressextractedCSS.Weareusingthispluginsothatpossible
//duplicatedCSSfromdifferentcomponentscanbededuped.
newOptimizeCSSPlugin({
assetNameRegExp:/\.css$/g,
cssProcessor:require('cssnano'),
cssProcessorOptions:{
discardComments:{removeAll:true},
//避免cssnano重新计算z-index
safe:true
},
canPrint:true
}),
],
module:{
rules:[
{
test:/\.(js|jsx)$/,
use:[
'babel-loader',
],
},
{
test:/\.(js|jsx)$/,
loader:'babel-loader',
exclude:/node_modules/,
},
{
test:/\.(css|pcss)$/,
use:ExtractTextPlugin.extract({
fallback:"style-loader",
use:"css-loader!postcss-loader"
})
},
{
test:/\.(png|jpg|gif|ttf|eot|woff|woff2|svg)$/,
loader:'url-loader?limit=8192&name=[name].[hash:8].[ext]&publicPath='+webpackFile.resourcePrefix+'&outputPath='+webpackFile.resource+'/'
},
{
test:/\.swf$/,
loader:'file?name=js/[name].[ext]'
}
]
}
});
letpages=entry;
for(letchunkNameinpages){
letconf={
filename:chunkName+'.html',
template:'index.html',
inject:true,
title:webpackCom.titleFun(chunkName,pages[chunkName][1]),
minify:{
removeComments:true,
collapseWhitespace:true,
removeAttributeQuotes:true
},
chunks:['manifest','vendor','common',chunkName],
hash:false,
chunksSortMode:'dependency'
};
config.plugins.push(newHtmlWebpackPlugin(conf));
}
/*清除dist*/
config.plugins.push(newCleanWebpackPlugin([webpackFile.proDirectory],{root:path.resolve(__dirname,'../../'),verbose:true,dry:false}));
/*拷贝静态资源*/
copyArr.map(function(data){
returnconfig.plugins.push(data)
});
module.exports=config;
构建多界面
整体架构搭建起来之后
app->component
$mkdirdemo&&cddemo
$touchIndex.jsx
importReactfrom'react';
classIndexextendsReact.Component{
render(){
return(
写个demo
在config->entry
module.exports=[
{
name:'index',
path:'index/Index.jsx',
title:'首页',
keywords:'首页',
description:'首页'
},
{
name:'demo',
path:'demo/Index.jsx',
title:'demo',
keywords:'demo',
description:'demo'
},
{
name:'demo1',
path:'demo1/Index.jsx',
title:'demo1',
keywords:'demo1',
description:'demo1'
}
];
然后直接执行npmruncreate-dev就会在devBuild和entryBuild中添加一个新的demo.html和demo.js
package.json
{
"name":"webpack_es6",
"version":"1.0.0",
"description":"",
"main":"index.js",
"scripts":{
"dev":"webpack-dev-server--devtooleval--progress--colors--profile--configconfig/webpack/webpack.dev.conf.js",
"entry":"nodeconfig/entry/entryBuild.js",
"devBuildHtml":"nodeconfig/webpack/webpack.devBuildHtml.conf.js",
"create-dev":"npmrunentry&&npmrundevBuildHtml",
"build":"BABEL_ENV=production&&webpack--progress--colors--configconfig/webpack/webpack.prod.conf.js",
"test":"echo\"Error:notestspecified\"&&exit1"
},
"keywords":[],
"author":"",
"license":"ISC",
"dependencies":{
"react":"^16.3.0",
"react-dom":"^16.3.0"
},
"devDependencies":{
"babel-cli":"^6.26.0",
"babel-eslint":"^8.2.2",
"babel-loader":"^7.1.4",
"babel-preset-env":"^1.6.1",
"babel-preset-react":"^6.24.1",
"babel-preset-react-hmre":"^1.1.1",
"cache-loader":"^1.2.2",
"clean-webpack-plugin":"^0.1.19",
"copy-webpack-plugin":"^4.5.1",
"css-loader":"^0.28.11",
"eslint":"^4.19.1",
"eslint-config-react-app":"^2.1.0",
"eslint-loader":"^2.0.0",
"eslint-plugin-flowtype":"^2.46.1",
"eslint-plugin-import":"^2.10.0",
"eslint-plugin-jsx-a11y":"^5.1.1",
"eslint-plugin-react":"^7.7.0",
"extract-text-webpack-plugin":"^4.0.0-beta.0",
"file":"^0.2.2",
"file-loader":"^1.1.11",
"html-webpack-plugin":"^3.1.0",
"optimize-css-assets-webpack-plugin":"^4.0.0",
"postcss-cssnext":"^3.1.0",
"postcss-loader":"^2.1.3",
"precss":"^3.1.2",
"react-dev-utils":"^5.0.0",
"style-loader":"^0.20.3",
"url-loader":"^1.0.1",
"webpack":"^4.4.1",
"webpack-cli":"^2.0.13",
"webpack-dev-server":"^3.1.1",
"webpack-merge":"^4.1.2"
},
"eslintConfig":{
"extends":"react-app",
"rules":{
"import/no-webpack-loader-syntax":0,
"no-script-url":0,
"jsx-a11y/href-no-hash":2
}
}
}
开发环境小技巧
在开发环境添加cache-loader可以提升在开发环境的编译速度
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。