Webpack configuration

webpack.common.js
webpack.dev.js
webpack.prod.js
webpack.umdcommon.js
webpack.umd.js
Copy the code

Startapp.js and buildapp.js are both packages of Webpack, and both commands have some common configuration, which is written in the webpack.common.js file

webpack.common.js

const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const HappyPack = require('happypack'); const WebpackBar = require('webpackbar'); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); const runtimePath = process.argv[8]; const APP_PATH = path.resolve(runtimePath, 'src'); Const {getPostCssConfigPath} = require('.. /util'); module.exports = { plugins: { HtmlWebpackPlugin, MiniCssExtractPlugin, CopyWebpackPlugin, }, config: Join (runtimePath, 'SRC ', 'index.js'),}, /** * exit */ output: {filename: process.env.NODE_ENV === 'production' ? '[name].[chunkhash].bundle.js' : '[name].[hash].bundle.js', chunkFilename: process.env.NODE_ENV === 'production' ? '[name].[chunkhash].bundle.js' : '[name].[hash].bundle.js', path: path.resolve(runtimePath, 'dist'), publicPath: }, plugins: [// HTML template new HtmlWebpackPlugin({title: '', // template HTML title filename: 'index.html', // template name template: path.join(runtimePath, 'SRC ', 'index.html'),// Template address hash: true, // prevent caching minify: {removeAttributeQuotes: true, // unquote}, chunks: [' index]}), / / the plugin will be according to the relative path of the module generates a four digit hash as a module id, Suggestions for the production environment of new webpack. HashedModuleIdsPlugin (), // Place CSS in a separate file new MiniCssExtractPlugin({filename: '[name].css', chunkFilename: '[id].css', ignoreOrder: false, // Enable to remove warnings about conflicting order }), / / in a separate process running on the TypeScript type checker Webpack plugin new ForkTsCheckerWebpackPlugin ({tsconfig: Path. join(runtimePath, 'tsconfig.json'), checkSyntacticErrors: true,}), // JSX and JS Babel parse new HappyPack({id: 'babel', loaders: [ 'cache-loader', { loader: 'babel-loader', query: { presets: [ [ '@babel/preset-env', { useBuiltIns: 'usage', // Use corejs3 to polyfill corejs: {version: 3, proposals: true},},], '@babel/preset-react',], plugins: [ '@babel/plugin-transform-runtime', '@babel/plugin-syntax-dynamic-import', '@babel/plugin-proposal-function-bind', '@babel/plugin-proposal-class-properties',],},},],}), // new HappyPack({id: 'ts', loaders: [{loader: 'ts-loader', options: { transpileOnly: true, happyPackMode: true, configFile: Path. join(runtimePath, 'tsconfig.json'),},},],}), // CSS parsing new HappyPack({id: 'CSS ', loaders: [ 'cache-loader', { loader: 'css-loader', options: { importLoaders: 1, }, }, { loader: 'postcss-loader', options: {config: {path: getPostCssConfigPath(runtimePath),},},},],}), // less new HappyPack({id: 'less', loaders: [ 'cache-loader', { loader: 'css-loader', options: { importLoaders: 1, }, }, { loader: 'postcss-loader', options: { config: { path: getPostCssConfigPath(runtimePath), }, }, }, { loader: 'less-loader', query: { javascriptEnabled: true, }, }, ], }), new WebpackBar({ reporters: ['profile'], profile: true }), ], optimization: { runtimeChunk: 'single', splitChunks: { cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all', }, }, }, }, module: { rules: [ { test: /\.m?jsx?$/, exclude: /(node_modules|bower_components)/, include: [APP_PATH], use: ['happypack/loader?id=babel'], }, { test: /\.m?tsx?$/, exclude: /(node_modules|bower_components)/, include: [APP_PATH], use: ['happypack/loader?id=ts'], }, { test: /\.css$/, include: [ APP_PATH, /highlight.js/, /photoswipe.css/, /default-skin.css/, /swiper.min.css/, /antd/, /antd-mobile/, /normalize.css/, ], use: [ process.env.NODE_ENV === 'development' ? 'style-loader' : MiniCssExtractPlugin.loader, 'happypack/loader?id=css', ], }, { test: /\.less$/, include: [APP_PATH, /normalize.less/], use: [ process.env.NODE_ENV === 'development' ? 'style-loader' : MiniCssExtractPlugin.loader, 'happypack/loader?id=less', ], }, { test: /\.(png|svg|jpg|gif|ico)$/, use: [ { loader: 'url-loader', options: { limit: 1024, }, }, ], }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ { loader: 'url-loader', options: { limit: 1024, }, }, ], }, { test: /\.(csv|tsv)$/, use: ['csv-loader'], }, { test: /\.xml$/, use: ['xml-loader'], }, { test: /\.ejs/, loader: ['ejs-loader?variable=data'], }, { test: /\.ya?ml$/, use: ['json-loader', 'yaml-loader'], }, ], }, resolve: { extensions: ['. Js', 'JSX' and 'ts',' benchmark ', 'less', 'CSS', 'json'], / / suffix auto-complete},,}}; Postcss.config. js config file getPostCssConfigPath(runtimePath) {if (fs.existssync (path.join(runtimePath, 'postcss.config.js'))) { return path.join(runtimePath, 'postcss.config.js'); } return path.join(__dirname, 'postcss.config.js'); }Copy the code

A lot of loaders and plug-ins are used in the common configuration, and the loader part is optimized. The optimization part mainly uses happypack, but also adds the parsing of less, and also uses postCSS-loader for autoprefixer operations. The rest of the configuration is the basic configuration, which is not covered here. It should be noted that there are two keys for exporting files, namely plugins and config

Once this public file is written, it’s time to implement the dev and prod configuration files

webpack.dev.js

const webpack = require('webpack'); const merge = require('webpack-merge'); const common = require('./webpack.common.js'); const commandArgs = require('.. /commandArgs'); const argsMap = commandArgs.initCommandArgs(); const customConfigPath = argsMap.get('--customconfig')[0]; let customModule; const curModule = merge(common.config, { mode: 'development', devtool: 'cheap-module-eval-source-map', devServer: { publicPath: '/', host: 'localhost', compress: true, port: 8000, clientLogLevel: HistoryApiFallback: true, overlay: true, // Browser displays error messages in full screen hot: true, // Start module hot update HMR open: Plugins: [new webpack.defineplugin ({process: {env: {NODE_ENV: JSON.stringify('development'), REAP_PATH: JSON.stringify(process.env.REAP_PATH), }, }, }), new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin(), ], }); const define = argsMap.get('--define')[0] || ''; if (customConfigPath) { customModule = require(customConfigPath); if (customModule && customModule.getConfig) { customModule.getConfig({ webpack, curModule, plugins: common.plugins, define: commandArgs.toCommandArgs(define), }); } } module.exports = curModule;Copy the code

There are separate Settings for the dev environment, mainly for webpack-dev-server

webpack.prod.js

const webpack = require('webpack'); const merge = require('webpack-merge'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const common = require('./webpack.common.js'); const commandArgs = require('.. /commandArgs'); const argsMap = commandArgs.initCommandArgs(); const customConfigPath = argsMap.get('--customconfig')[0]; let customModule; const curModule = merge(common.config, { mode: 'production', plugins: [ new CleanWebpackPlugin(), new webpack.DefinePlugin({ process: { env: { NODE_ENV: JSON.stringify('production'), REAP_PATH: JSON.stringify(process.env.REAP_PATH), }, }, }), ], }); const define = argsMap.get('--define')[0] || ''; if (customConfigPath) { customModule = require(customConfigPath); if (customModule && customModule.getConfig) { customModule.getConfig({ webpack, curModule, plugins: common.plugins, define: commandArgs.toCommandArgs(define), }); } } module.exports = curModule;Copy the code

There are separate parameter Settings for the PROD environment.

Either dev or Prod will eventually look for the user’s configuration file in the customCinfigPath parameter. If the user doesn’t pass this parameter, it will look for the ctbuild.config.js configuration file, which will add webpack and the current configuration, All plugins and other command-line parameters are passed to getConfig, and the user makes a modification to the passed configuration in the configuration file to achieve a custom configuration effect.

Webpack.dev. js and webpack.prod.js are used to compile host projects, not packge projects. If a host project is written in typescript, We can use ts-loader and fork-ts-checker-webpack-plugin to parse, see the above code for details.

Next, we’ll look at the babel.config.js file, which is used to configure Babel parsing. This configuration file is located at the root of the package project and is used when startApp, buildApp, and buildPackage are executed.

babel.config.js

Const presets = [['@babel/preset-env', {// Polyfill useBuiltIns: 'usage', // Use corejs3 to polyfill corejs: { version: 3, proposals: true }, }, ], '@babel/preset-react', ]; const plugins = [ '@babel/plugin-transform-runtime', '@babel/plugin-syntax-dynamic-import', '@babel/plugin-proposal-function-bind', '@babel/plugin-proposal-optional-chaining', // You can use the decorator mode ['@babel/plugin-proposal-decorators', {legacy: true }], ['@babel/plugin-proposal-class-properties', { loose: true }], ]; module.exports = { presets, plugins };Copy the code

Startapp.js, BuildApp.js, buildPackage.js, and BuildPackagets.js are covered in detail

   github

  • Write a WebPack-based React packaging tool (1)
  • Write a WebPack-based React packaging tool (2)
  • Write a WebPack-based React packaging tool (3)
  • Write a WebPack-based React packaging tool (4)
  • Write a WebPack-based React packaging tool (5)
  • Write a WebPack-based React packaging tool (6)