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');//引入webpackconst 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 可以提升在開發環境的編譯速度
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。
新聞熱點
疑難解答