webpack4 + react 搭建多页面应用示例
程序员文章站
2022-03-10 20:59:51
webpack 升级到4之后还没好好的同步一个可实用的webpack架子,接下来用webpack4来搭建一个简单的react的多界面应用,废话不说 直接撸码
创建工程...
webpack 升级到4之后还没好好的同步一个可实用的webpack架子,接下来用webpack4来搭建一个简单的react的多界面应用,废话不说 直接撸码
创建工程
$ mkdir demo && cd demo $ npm init -y
webpack 配置
安装react + babel 依赖
$ npm i -s react@16.3.0 react-dom@16.3.0 $ npm i -d webpack@4.4.1 webpack-cli@2.0.13 webpack-dev-server@3.1.1 webpack-merge@4.1.2 babel-cli@6.26.0 babel-preset-env@1.6.1 babel-preset-react@6.24.1 babel-preset-react-hmre@1.1.1 babel-loader@7.1.4 file-loader@1.1.11 url-loader@1.0.1
webpack.base.conf.js(config -> webpack)
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
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'), }, ], 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
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", name: "common", minchunks: 2, maxinitialrequests: 5, minsize: 0 }, vendor: { //第三方组件 test: /node_modules/, chunks: "initial", name: "vendor", priority: 10, enforce: true } } } }, 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 }), ], 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]' } ] } }); 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
$ mkdir demo && cd demo $ touch index.jsx import react from 'react'; class index extends react.component { render() { return ( <div classname="demo"> 写个demo </div> ); } } export default index;
在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' } ];
然后直接执行 npm run create-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 --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 可以提升在开发环境的编译速度
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。