webpack4 + react 搭建多页面应用示例

webpack 升级到4之后还没好好的同步一个可实用的webpack架子,接下来用webpack4来搭建一个简单的react的多界面应用,废话不说 直接撸码

创建工程

rush:bash;"> $ mkdir demo && cd demo $ npm init -y

webpack 配置

安装react + babel 依赖

webpack.base.conf.js(config -> webpack)

rush:js;"> const entry = require("./webpack.entry.conf"); const newEntry = {}; for (let name in entry) { newEntry[name] = entry[name][0] } let config = { entry: newEntry,resolve: { extensions: [".js",".json",".jsx",".css",".pcss"],} }; module.exports = config;

webpack.dev.conf.js

rush:js;"> const webpack = require('webpack');//引入webpack const opn = require('opn');//打开浏览器 const merge = require('webpack-merge');//webpack配置文件合并 const path = require("path"); const baseWebpackConfig = require("./webpack.base.conf");//基础配置 const webpackFile = require("./webpack.file.conf");//一些路径配置 const eslintFormatter = require('react-dev-utils/eslintFormatter');

let config = 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: [
/设置热更新/
new webpack.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'),"../../app")
],}
]
},/设置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

rush:js;"> const path = require('path'); const merge = require('webpack-merge'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const copyWebpackPlugin = require('copy-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const OptimizeCssplugin = require('optimize-css-assets-webpack-plugin'); const ExtractTextPlugin = require("extract-text-webpack-plugin"); const baseWebpackConfig = require("./webpack.base.conf"); const webpackFile = require('./webpack.file.conf'); const entry = require("./webpack.entry.conf"); const webpackCom = require("./webpack.com.conf");

let config = 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",vendor: { //第三方组件
test: /node_modules/,plugins: [
// extract css into its own file
new ExtractTextPlugin('css/[name].[md5:contenthash:hex:8].css'),// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCssplugin({
assetNameRegExp: /.css$/g,cssprocessor: require('cssnano'),cssprocessorOptions: {
discardComments: {removeAll: true},// 避免 cssnano 重新计算 z-index
safe: true
},canPrint: true
}),loader: 'babel-loader',exclude: /node_modules/,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]'
}
]
}
});
let pages = entry;
for (let chunkName in pages) {
let conf = {
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(new HtmlWebpackPlugin(conf));
}
/ 清除 dist /
config.plugins.push(new CleanWebpackPlugin([webpackFile.proDirectory],{root: path.resolve(__dirname,'../../'),verbose: true,dry: false}));

/ 拷贝静态资源 /
copyArr.map(function (data) {
return config.plugins.push(data)
});

module.exports = config;

构建多界面

整体架构搭建起来之后

app -> component

rush:js;"> $ mkdir demo && cd demo $ touch Index.jsx import React from 'react'; class Index extends React.Component { render() { return (
); } } export default Index;

在config -> entry

rush:js;"> 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' } ];

然后直接执行 npm run create-dev 就会在devBuild 和 entryBuild 中添加一个新的demo.html 和 demo.js

rush:js;"> package.json

{
"name": "webpack_es6","version": "1.0.0","description": "","main": "index.js","scripts": {
"dev": "webpack-dev-server --devtool eval --progress --colors --profile --config config/webpack/webpack.dev.conf.js","entry": "node config/entry/entryBuild.js","devBuildHtml": "node config/webpack/webpack.devBuildHtml.conf.js","create-dev": "npm run entry && npm run devBuildHtml","build": "BABEL_ENV=production && webpack --progress --colors --config config/webpack/webpack.prod.conf.js","test": "echo \"Error: no test specified\" && exit 1"
},"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 可以提升在开发环境的编译速度

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...