From 2a36e7ce0febae1e04bec2bb8d92983dc32b71ba Mon Sep 17 00:00:00 2001 From: crupest Date: Mon, 24 Aug 2020 01:20:37 +0800 Subject: Migrate to webpack chain. --- Timeline/ClientApp/package.json | 3 +- Timeline/ClientApp/webpack.common.js | 142 ++++++++++++++++++++---------- Timeline/ClientApp/webpack.config.dev.js | 123 ++++++++------------------ Timeline/ClientApp/webpack.config.prod.js | 96 +++++--------------- 4 files changed, 159 insertions(+), 205 deletions(-) diff --git a/Timeline/ClientApp/package.json b/Timeline/ClientApp/package.json index 3c06baff..e45b6079 100644 --- a/Timeline/ClientApp/package.json +++ b/Timeline/ClientApp/package.json @@ -78,7 +78,6 @@ "@typescript-eslint/eslint-plugin": "^3.6.1", "@typescript-eslint/parser": "^3.6.1", "@yarnpkg/pnpify": "^2.1.0", - "autoprefixer": "^9.8.0", "babel-loader": "^8.1.0", "babel-plugin-transform-builtin-extend": "^1.1.2", "clean-webpack-plugin": "^3.0.0", @@ -96,6 +95,7 @@ "http-server": "^0.12.3", "pnp-webpack-plugin": "^1.6.4", "postcss-loader": "^3.0.0", + "postcss-preset-env": "^6.7.0", "prettier": "^2.0.5", "sass": "^1.26.8", "sass-loader": "^9.0.2", @@ -104,6 +104,7 @@ "typescript": "^3.9.7", "url-loader": "^4.1.0", "webpack": "^4.43.0", + "webpack-chain": "^6.5.1", "webpack-cli": "^3.3.11", "webpack-dev-server": "^3.11.0", "workbox-webpack-plugin": "^5.1.3" diff --git a/Timeline/ClientApp/webpack.common.js b/Timeline/ClientApp/webpack.common.js index bed968e1..a5dce879 100644 --- a/Timeline/ClientApp/webpack.common.js +++ b/Timeline/ClientApp/webpack.common.js @@ -1,48 +1,100 @@ -const autoprefixer = require('autoprefixer'); +const path = require('path'); const htmlWebpackTemplate = require('html-webpack-template'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const PnpWebpackPlugin = require('pnp-webpack-plugin'); +const postcssPresetEnv = require('postcss-preset-env'); +const Config = require('webpack-chain'); -const commonRules = [ - { - test: /\.css$/, - use: ['style-loader', 'css-loader'], - }, - { - test: /\.(scss|sass)$/, - use: [ - 'style-loader', - 'css-loader', - { - loader: 'postcss-loader', - options: { - plugins: function () { - return [autoprefixer]; - }, - }, - }, - 'sass-loader', - ], - }, - { - test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot)$/i, - use: [ - { - loader: 'url-loader', - options: { - limit: 8192, - }, - }, - ], - }, -]; +const config = new Config(); + +config.entry('index').add(path.resolve(__dirname, 'src/app/index.tsx')); + +config.module + .rule('ts') + .test(/\.ts(x?)$/) + .exclude.add(/node_modules/) + .end() + .use('babel') + .loader('babel-loader') + .end() + .use('ts') + .loader('ts-loader') + .end(); + +config.module + .rule('js') + .test(/\.js(x?)$/) + .exclude.add(/node_modules/) + .end() + .use('babel') + .loader('babel-loader') + .end(); -const htmlCommonConfig = { - inject: false, - template: htmlWebpackTemplate, +config.module + .rule('css') + .test(/\.css$/) + .use('style') + .loader('style-loader') + .end() + .use('css') + .loader('css-loader') + .end(); - appMountId: 'app', - mobile: true, +config.module + .rule('sass') + .test(/\.(scss|sass)$/) + .use('style') + .loader('style-loader') + .end() + .use('css') + .loader('css-loader') + .end() + .use('postcss') + .loader('postcss-loader') + .options({ + plugins: () => [postcssPresetEnv(/* pluginOptions */)], + }) + .end() + .use('sass') + .loader('sass-loader') + .end(); - headHtmlSnippet: ` +config.module + .rule('file') + .test(/\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot)$/i) + .use('url') + .loader('url-loader') + .options({ + limit: 8192, + }); + +config.resolve.extensions + .add('*') + .add('.js') + .add('.jsx') + .add('.ts') + .add('.tsx') + .end() + .plugin('pnp') + .use(PnpWebpackPlugin); + +config.resolveLoader.plugin('pnp').use(PnpWebpackPlugin.moduleLoader(module)); + +config.output + .path(path.resolve(__dirname, 'dist/')) + .filename('[name].[hash].js') + .chunkFilename('[name].[hash].js') + .publicPath('/'); + +config.plugin('html').use(HtmlWebpackPlugin, [ + { + inject: false, + template: htmlWebpackTemplate, + + appMountId: 'app', + mobile: true, + + headHtmlSnippet: ` @@ -51,10 +103,8 @@ const htmlCommonConfig = { `, - title: 'Timeline', -}; + title: 'Timeline', + }, +]); -module.exports = { - commonRules, - htmlCommonConfig, -}; +module.exports = config; diff --git a/Timeline/ClientApp/webpack.config.dev.js b/Timeline/ClientApp/webpack.config.dev.js index fe5528ce..840ac24a 100644 --- a/Timeline/ClientApp/webpack.config.dev.js +++ b/Timeline/ClientApp/webpack.config.dev.js @@ -1,95 +1,46 @@ const path = require('path'); const webpack = require('webpack'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); -const PnpWebpackPlugin = require('pnp-webpack-plugin'); -const { commonRules, htmlCommonConfig } = require('./webpack.common'); +const config = require('./webpack.common'); -module.exports = (env) => { - const entry = ['react-hot-loader/patch', './src/app/index.tsx']; +config.mode('development'); + +config.entry('index').add('react-hot-loader/patch'); + +config.module + .rule('ts') + .use('babel') + .options({ + plugins: ['react-hot-loader/babel'], + }); + +config.module + .rule('js') + .use('babel') + .options({ + plugins: ['react-hot-loader/babel'], + }); + +config.devtool('eval-cheap-module-source-map'); +config.resolve.alias.set('react-dom', '@hot-loader/react-dom'); + +config.devServer + .contentBase(path.resolve(__dirname, 'public/')) + .host('0.0.0.0') + .port(3000) + .historyApiFallback(true) + .hotOnly(true) + .allowedHosts.add('.myide.io'); + +config.plugin('hot').use(webpack.HotModuleReplacementPlugin); + +module.exports = (env) => { if (env && env.TIMELINE_USE_MOCK_BACKEND) { - entry.push(path.join(__dirname, 'src/app/http/mock/install.ts')); + config + .entry('index') + .add(path.join(__dirname, 'src/app/http/mock/install.ts')); } - return { - entry, - mode: 'development', - devtool: 'eval-cheap-module-source-map', - module: { - rules: [ - ...commonRules, - { - test: /\.ts(x?)$/, - exclude: /node_modules/, - use: [ - { - loader: 'babel-loader', - options: { - plugins: ['react-hot-loader/babel'], - }, - }, - { - loader: 'ts-loader', - }, - ], - }, - { - test: /\.js(x?)$/, - exclude: /node_modules/, - use: [ - { - loader: 'babel-loader', - options: { - plugins: ['react-hot-loader/babel'], - }, - }, - ], - }, - ], - }, - resolve: { - alias: { - 'react-dom': '@hot-loader/react-dom', - }, - extensions: ['*', '.js', '.jsx', '.ts', '.tsx'], - plugins: [PnpWebpackPlugin], - }, - resolveLoader: { - plugins: [PnpWebpackPlugin.moduleLoader(module)], - }, - optimization: { - runtimeChunk: 'single', - splitChunks: { - chunks: 'all', - cacheGroups: { - vendor: { - test: /[\\/]node_modules[\\/]/, - name: 'vendors', - chunks: 'all', - }, - }, - }, - }, - output: { - path: path.resolve(__dirname, 'dist/'), - filename: '[name].[hash].js', - chunkFilename: '[name].[hash].js', - publicPath: '/', - }, - devServer: { - contentBase: path.resolve(__dirname, 'public/'), - host: '0.0.0.0', - port: 3000, - historyApiFallback: true, - hotOnly: true, - allowedHosts: ['.myide.io'], - }, - plugins: [ - new HtmlWebpackPlugin({ - ...htmlCommonConfig, - }), - new webpack.HotModuleReplacementPlugin(), - ], - }; + return config.toConfig(); }; diff --git a/Timeline/ClientApp/webpack.config.prod.js b/Timeline/ClientApp/webpack.config.prod.js index d0c72381..e3ef65e1 100644 --- a/Timeline/ClientApp/webpack.config.prod.js +++ b/Timeline/ClientApp/webpack.config.prod.js @@ -1,84 +1,36 @@ const path = require('path'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); const CopyPlugin = require('copy-webpack-plugin'); const WorkboxPlugin = require('workbox-webpack-plugin'); -const PnpWebpackPlugin = require('pnp-webpack-plugin'); -const { commonRules, htmlCommonConfig } = require('./webpack.common'); +const config = require('./webpack.common'); -const config = { - entry: ['./src/app/index.tsx', './src/app/service-worker.tsx'], - mode: 'production', - devtool: 'source-map', - module: { - rules: [ - ...commonRules, - { - test: /\.ts(x?)$/, - exclude: /node_modules/, - use: [ - { - loader: 'babel-loader', - }, - { - loader: 'ts-loader', - }, - ], - }, +config.mode('production'); + +config + .entry('index') + .add(path.resolve(__dirname, 'src/app/service-worker.tsx')); + +config.devtool('source-map'); + +config.plugin('clean').use(CleanWebpackPlugin); + +config.plugin('copy').use(CopyPlugin, [ + { + patterns: [ { - test: /\.js(x?)$/, - exclude: /node_modules/, - use: [ - { - loader: 'babel-loader', - }, - ], + from: path.resolve(__dirname, 'public/'), + to: path.resolve(__dirname, 'dist/'), }, ], }, - resolve: { - extensions: ['*', '.js', '.jsx', '.ts', '.tsx'], - plugins: [PnpWebpackPlugin], - }, - resolveLoader: { - plugins: [PnpWebpackPlugin.moduleLoader(module)], - }, - optimization: { - runtimeChunk: 'single', - splitChunks: { - chunks: 'all', - cacheGroups: { - vendor: { - test: /[\\/]node_modules[\\/]/, - name: 'vendors', - chunks: 'all', - }, - }, - }, - }, - output: { - path: path.resolve(__dirname, 'dist/'), - filename: '[name].[hash].js', - chunkFilename: '[name].[hash].js', - publicPath: '/', +]); + +config.plugin('workbox').use(WorkboxPlugin.InjectManifest, [ + { + swSrc: path.resolve(__dirname, 'src/sw/sw.ts'), + maximumFileSizeToCacheInBytes: 15000000, }, - plugins: [ - new CleanWebpackPlugin(), - new HtmlWebpackPlugin(htmlCommonConfig), - new CopyPlugin({ - patterns: [ - { - from: path.resolve(__dirname, 'public/'), - to: path.resolve(__dirname, 'dist/'), - }, - ], - }), - new WorkboxPlugin.InjectManifest({ - swSrc: './src/sw/sw.ts', - maximumFileSizeToCacheInBytes: 15000000, - }), - ], -}; +]); -module.exports = config; +module.exports = config.toConfig(); -- cgit v1.2.3