Created
May 18, 2020 18:19
-
-
Save studentIvan/cbf18165ee7e4b6b286b6bf1fefcec05 to your computer and use it in GitHub Desktop.
Preact 8 with CLI configuration example.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable */ | |
import path from 'path'; | |
import fs from 'fs'; | |
import webpack from 'webpack'; | |
import HtmlWebpackInlineSVGPlugin from 'html-webpack-inline-svg-plugin'; | |
import SVGSpritemapPlugin from 'svg-spritemap-webpack-plugin'; | |
// import { WebpackBundleSizeAnalyzerPlugin } from 'webpack-bundle-size-analyzer'; | |
import packageData from '../../package.json'; | |
import pathsResolveConfig from './paths.resolve.config'; | |
import appPackageData from '../../../mobile-app/package.json'; | |
import config from '../index'; | |
const appSettings = config; | |
/** | |
* Function that mutates original webpack config. | |
* Supports asynchronous changes when promise is returned. | |
* | |
* @param {object} config - original webpack config. | |
* @param {object} env - options passed to CLI. | |
* @param {WebpackConfigHelpers} helpers - object with useful helpers when working with config. | |
*/ | |
export default function (config, env, helpers) { | |
const PRODUCTION_MODE = process.env.NODE_ENV === 'production'; | |
/** setup app version and gtm settings */ | |
const htmlWebpackPlugin = helpers | |
.getPluginsByName(config, 'HtmlWebpackPlugin')[0]; | |
htmlWebpackPlugin.plugin.options.appVersion = packageData.version; | |
htmlWebpackPlugin.plugin.options.fbqInitId = appSettings.fbqInitId.ridestore; | |
htmlWebpackPlugin.plugin.options.gtmId = appSettings.gtmId.ridestore; | |
htmlWebpackPlugin.plugin.options.analyticsId = appSettings.analyticsId; | |
htmlWebpackPlugin.plugin.options.buildEnv = PRODUCTION_MODE ? '1' : '0'; | |
htmlWebpackPlugin.plugin.options.appBundleVersion = appPackageData.version; | |
/** configure css modules */ | |
const cssLoaderOptions = helpers | |
.getLoadersByName(config, 'css-loader')[0].rule.loader[2].options; | |
const cssLoader2Options = helpers | |
.getLoadersByName(config, 'css-loader')[1].rule.loader[2].options; | |
cssLoaderOptions.modules = true; | |
cssLoaderOptions.localIdentName = '[local]'; | |
cssLoaderOptions.importLoaders = 1; | |
cssLoaderOptions.sourceMap = false; | |
cssLoader2Options.modules = true; | |
cssLoader2Options.localIdentName = '[local]'; | |
cssLoader2Options.importLoaders = 1; | |
cssLoader2Options.sourceMap = false; | |
const mobileEntry = path.join(__dirname, '../../src/package', 'mobile.package.js'); | |
/** entry point */ | |
config.resolve.alias['preact-cli-entrypoint'] = mobileEntry; | |
/** import paths */ | |
config.resolve.alias = Object.assign(config.resolve.alias, pathsResolveConfig); | |
config.output.publicPath = './'; // public path is ./ not | |
const htmlPlugin = helpers | |
.getPluginsByName(config, 'HtmlWebpackPlugin')[0]; | |
htmlPlugin.plugin.options.minify = false; // don't minify html | |
const possibleSize = PRODUCTION_MODE ? 8e5 : 8e6; | |
config.performance.maxAssetSize = possibleSize; | |
config.performance.maxEntrypointSize = possibleSize; | |
const commonChunkPlugin = helpers | |
.getPluginsByName(config, 'CommonsChunkPlugin')[0]; | |
config.plugins.splice(commonChunkPlugin.index, 1); | |
config.plugins.push(new webpack.optimize.LimitChunkCountPlugin({ | |
maxChunks: 1, // Must be greater than or equal to one | |
minChunkSize: 1000 | |
})); | |
config.plugins = (config.plugins || []).concat( | |
new SVGSpritemapPlugin({ | |
src: path.join(__dirname, '../../src/assets/svg/*.svg'), | |
svgo: true, | |
}) | |
); | |
config.plugins.push( | |
new webpack.NormalModuleReplacementPlugin( | |
/RSIconSvg\.component/, | |
path.join(__dirname, '../../src/lib/components/includes/ui-components/svg/RSIconSvg/RSIconSvg.mobile.component.js') | |
) | |
); | |
// config.plugins.push(new WebpackBundleSizeAnalyzerPlugin('./plain-report.txt')); | |
config.plugins.push(new HtmlWebpackInlineSVGPlugin()); | |
/** ignore desktop modules */ | |
config.plugins.push(new webpack.IgnorePlugin(/\.dt/)); | |
/** using preact-compat with webpack */ | |
Object.assign(config.resolve.alias, { | |
'react': 'preact-compat', | |
'react-dom': 'preact-compat', | |
// Not necessary unless you consume a module using `createClass` | |
'create-react-class': 'preact-compat/lib/create-react-class', | |
}); | |
const uglifyJSPluginData = helpers | |
.getPluginsByName(config, 'UglifyJsPlugin')[0]; | |
// if (PRODUCTION_MODE) { | |
if (uglifyJSPluginData) { | |
/** turn the uglify to sourcemap reduce mode if it presents */ | |
uglifyJSPluginData.plugin.options.sourceMap = false; | |
} | |
/** reduce the bundle size without source maps */ | |
config.devtool = 'none'; | |
// } | |
// else if (uglifyJSPluginData) { | |
// /** better debugging */ | |
// uglifyJSPluginData.plugin.options.output.beautify = true; | |
// uglifyJSPluginData.plugin.options.output.comments = true; | |
// uglifyJSPluginData.plugin.options.mangle = false; | |
// uglifyJSPluginData.plugin.options.compress = false; | |
// } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable */ | |
const path = require('path'); | |
module.exports = { | |
'@services': path.join(__dirname, '../../src/lib/services'), | |
'@rest': path.join(__dirname, '../../src/lib/rest/'), | |
'@hocs': path.join(__dirname, '../../src/lib/hocs'), | |
'@test': path.join(__dirname, '../../src/lib/test'), | |
'@style': path.join(__dirname, '../../src/lib/style'), | |
'@classes': path.join(__dirname, '../../src/lib/classes'), | |
'@common': path.join(__dirname, '../../src/lib/common'), | |
'@services/language/no-chunk-version': path.join(__dirname, '../../src/lib/services/language/no-chunk-version'), | |
'@ui-components': path.join(__dirname, '../../src/lib/components/includes/ui-components'), | |
'@router': path.join(__dirname, '../../src/lib/components/includes/router'), | |
'@app': path.join(__dirname, '../../src/lib/components/general/app'), | |
'@pages': path.join(__dirname, '../../src/lib/components/general/pages/'), | |
'@config': path.join(__dirname, '../'), | |
'@util': path.join(__dirname, '../../util'), | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable */ | |
import path from 'path'; | |
import fs from 'fs'; | |
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; | |
import packageData from '../../package.json'; | |
import pathsResolveConfig from './paths.resolve.config'; | |
import webpack from 'webpack'; | |
import SVGSpritemapPlugin from 'svg-spritemap-webpack-plugin'; | |
import SWPrecacheWebpackPlugin from 'sw-precache-webpack-plugin'; | |
import classNamesFn from './classnames.function'; | |
const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); | |
const ManifestPlugin = require('webpack-manifest-plugin'); | |
const v8 = require('v8'); | |
v8.setFlagsFromString('--max-old-space-size=2048'); | |
const totalHeapSize = v8.getHeapStatistics().total_available_size; | |
let totalHeapSizaInMB = (totalHeapSize / 1024 / 1024).toFixed(2); | |
console.log('NodeJS version', process.version); | |
console.log('V8 Total Heap Size', totalHeapSizaInMB, 'MB'); | |
/** | |
* Function that mutates original webpack config. | |
* Supports asynchronous changes when promise is returned. | |
* | |
* @param {object} config - original webpack config. | |
* @param {object} env - options passed to CLI. | |
* @param {WebpackConfigHelpers} helpers - object with useful helpers when working with config. | |
*/ | |
export default function (config, env, helpers) { | |
const PRODUCTION_MODE = process.env.NODE_ENV === 'production'; | |
const BOOST_MODE = process.env.BOOST_BUILD == '1'; | |
const appSettings = require('../index'); | |
const webEntry = path.join(__dirname, '../../src/package', 'web.entry.js'); | |
const webPackage = path.join(__dirname, '../../src/package', 'web.package.js'); | |
const isESMBuild = process.env.BABEL_ENV === 'esm'; | |
/** replace preact cli entry to web entry */ | |
if (config.entry.bundle) { | |
config.entry.bundle = [webEntry]; | |
} | |
if (config.entry.polyfills) { | |
config.entry.polyfills = [config.entry.polyfills]; | |
} | |
/** setup app version and gtm settings */ | |
const htmlWebpackPlugin = helpers | |
.getPluginsByName(config, 'HtmlWebpackPlugin')[0]; | |
if (htmlWebpackPlugin) { | |
htmlWebpackPlugin.plugin.options.appVersion = packageData.version; | |
htmlWebpackPlugin.plugin.options.fbqInitId = appSettings.fbqInitId.ridestore; | |
htmlWebpackPlugin.plugin.options.gtmId = appSettings.gtmId.ridestore; | |
htmlWebpackPlugin.plugin.options.analyticsId = appSettings.analyticsId; | |
htmlWebpackPlugin.plugin.options.buildEnv = PRODUCTION_MODE ? '1' : '0'; | |
htmlWebpackPlugin.plugin.options.codeVersionTag = appSettings.codeVersionTag; | |
} | |
const extractTextPluginData = helpers | |
.getPluginsByName(config, 'ExtractTextPlugin')[0]; | |
if (extractTextPluginData) { | |
extractTextPluginData.plugin.filename = 'style.' + appSettings.codeVersionTag + '.css'; | |
} | |
/** configure css modules */ | |
const firstStyleRule = helpers.getLoadersByName(config, 'css-loader')[0].rule; | |
const secondStyleRule = helpers.getLoadersByName(config, 'css-loader')[1].rule; | |
const firstCSSLoaderRules = firstStyleRule.loader; | |
const secondCSSLoaderRules = secondStyleRule.loader; | |
const cssLoaderOptions1 = firstCSSLoaderRules.filter(x => x.loader === 'css-loader')[0].options; | |
const cssLoaderOptions2 = secondCSSLoaderRules.filter(x => x.loader === 'css-loader')[0].options; | |
/** post css turned off */ | |
firstCSSLoaderRules.splice(firstCSSLoaderRules.length - 1, 1); | |
secondCSSLoaderRules.splice(secondCSSLoaderRules.length - 1, 1); | |
cssLoaderOptions1.modules = true; | |
cssLoaderOptions1.getLocalIdent = classNamesFn; | |
cssLoaderOptions1.importLoaders = 1; | |
cssLoaderOptions1.sourceMap = !PRODUCTION_MODE; | |
cssLoaderOptions2.modules = cssLoaderOptions1.modules; | |
cssLoaderOptions2.getLocalIdent = cssLoaderOptions1.getLocalIdent; | |
cssLoaderOptions2.importLoaders = cssLoaderOptions1.importLoaders; | |
cssLoaderOptions2.sourceMap = cssLoaderOptions1.sourceMap; | |
config.resolve.extensions = ['.js', '.jsx', '.ts', '.tsx', '.json', '.scss', '.css']; | |
const babelLoader = helpers.getLoadersByName(config, 'babel-loader')[0]; | |
babelLoader.rule.options.cacheDirectory = true; | |
/** entry point */ | |
config.resolve.alias['preact-cli-entrypoint'] = webPackage; | |
/** import paths */ | |
config.resolve.alias = Object.assign(config.resolve.alias, pathsResolveConfig); | |
if (config.entry['ssr-bundle']) { | |
config.entry['ssr-bundle'] = [webPackage]; | |
} | |
config.output.filename = !env.ssr ? '[name].' + appSettings.codeVersionTag + '.js' : '[name].js'; | |
config.output.chunkFilename = PRODUCTION_MODE ? '[name].[chunkhash].chunk.js' : '[name].chunk.js'; | |
config.performance = { | |
maxEntrypointSize: 400e3, | |
maxAssetSize: 200e3, | |
}; | |
if (!env.ssr) { | |
/** BundleAnalyzerPlugin */ | |
if (appSettings.generateBundleAnalyze) { | |
config.plugins.push( | |
new BundleAnalyzerPlugin(!env.production | |
? { analyzerPort: 8089, openAnalyzer: false } | |
: { openAnalyzer: false, analyzerMode: 'static' } | |
) | |
); | |
} | |
} | |
else if (env.ssr) { | |
config.performance = { | |
maxEntrypointSize: 2500e3, | |
maxAssetSize: 2500e3, | |
}; | |
global.isServerSideApp = true; | |
const commonChunkPlugin = helpers | |
.getPluginsByName(config, 'CommonsChunkPlugin')[0]; | |
config.plugins.splice(commonChunkPlugin.index, 1); | |
config.plugins.push(new webpack.optimize.LimitChunkCountPlugin({ | |
maxChunks: 1, // Must be greater than or equal to one | |
minChunkSize: 1000 | |
})); | |
} | |
/** using preact-compat with webpack */ | |
Object.assign(config.resolve.alias, { | |
'react': 'preact-compat', | |
'react-dom': 'preact-compat', | |
// Not necessary unless you consume a module using `createClass` | |
'create-react-class': 'preact-compat/lib/create-react-class' | |
}); | |
config.plugins = (config.plugins || []).concat( | |
new SVGSpritemapPlugin({ | |
src: path.join(__dirname, '../../src/assets/svg/*.svg'), | |
svgo: true, | |
}) | |
); | |
config.plugins.push(new ManifestPlugin({ | |
fileName: 'chunk-manifest.json', | |
})); | |
if (PRODUCTION_MODE && (env.production || env.ssr)) { | |
const swPrecachePluginData = helpers | |
.getPluginsByName(config, 'SWPrecacheWebpackPlugin')[0]; | |
if (swPrecachePluginData) { | |
config.plugins.splice(swPrecachePluginData.index, 1); | |
config.plugins.push(new SWPrecacheWebpackPlugin({ | |
cacheId: 'rs-pwa', | |
dontCacheBustUrlsMatching: /(\.\w{8}\.|^\/(v|cdntest|api|order|track|config|index\.php|admin|login|skin|js\/|media\/|translations\/|mag|ajaxwishlist|rsrest|ordermanagement|smsmanager|dynamicshipping|klarna|reviewemail|paymentaddon|connector|monkey|storecredit|paypal|xmlconnect|DragDrop|reclaim))/, | |
filename: 'sw.js', | |
handleFetch: false, | |
minify: true, | |
runtimeCaching: [ | |
{ urlPattern: /\/(v|cdntest)$/, handler: 'networkOnly' }, | |
{ urlPattern: /^\/(api\/|order|track|config|index\.php|admin|login|skin|js\/|media\/|translations\/|mag|ajaxwishlist|rsrest|ordermanagement|smsmanager|dynamicshipping|klarna|reviewemail|paymentaddon|connector|monkey|storecredit|paypal|xmlconnect|DragDrop|reclaim)/, handler: 'networkOnly' }, | |
{ urlPattern: /^\/cache-management\/menu\/flush/, handler: 'networkOnly' }, | |
], | |
// navigateFallback: '/index.html', | |
navigateFallback: false, | |
directoryIndex: '/index.html', | |
mergeStaticsConfig: true, | |
staticFileGlobsIgnorePatterns: [ | |
/polyfills(\..*)?\.js$/, | |
/\.map$/, | |
/push-manifest\.json$/, | |
/([a-z0-9]+)\.(ttf|eot)$/, | |
/\.(DS_Store|png\.js|jpg\.js)$/, | |
/circularfont/, | |
/muli/, | |
/playfair/, | |
/safari-pinned-tab/, | |
/mstile-150x150/, | |
/\/assets\/favicon\.ico$/, | |
/\/assets\/images\/selector-arrow\.png$/, | |
/\/assets\/svg\/([a-z0-9-]+)\.svg$/, | |
/\/style\.([a-z0-9]+)\.([a-z0-9]+)\.css$/, | |
], | |
})); | |
const pushManifestPlugin = helpers.getPluginsByName(config, 'PushManifestPlugin')[0]; | |
config.plugins.splice(pushManifestPlugin.index, 1); | |
} | |
const uglifyJSPluginData = helpers | |
.getPluginsByName(config, 'UglifyJsPlugin')[0]; | |
if (uglifyJSPluginData) { | |
const opts = uglifyJSPluginData.plugin.options; | |
if (isESMBuild || BOOST_MODE) { | |
config.plugins.splice(uglifyJSPluginData.index, 1); | |
} | |
else { | |
/** turn the uglify to sourcemap reduce mode if it presents */ | |
opts.sourceMap = false; | |
opts.ie8 = false; | |
opts.parallel = BOOST_MODE || appSettings.parallelBuild; | |
opts.warningsFilter = (warning, source) => { | |
if (/Dropping unreachable code/i.test(warning)) { | |
return true; | |
} | |
if (/filename\.js/i.test(source)) { | |
return true; | |
} | |
return false; | |
}; | |
const ujsp = new UglifyJsPlugin(Object.assign({}, opts)); | |
config.plugins[uglifyJSPluginData.index] = ujsp; | |
} | |
} | |
/** reduce the bundle size without source maps */ | |
config.devtool = 'none'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const paths = require('./paths.resolve.config'); | |
// webpack.config.js for eslint | |
module.exports = { | |
resolve: { | |
extensions: ['', '/index.js', '/index.jsx', '.jsx', '.js', '.json'], | |
alias: paths, | |
}, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment