The original link
Webpack upgrade optimization – Remember a product-side upgrade
Recently, a new product needs to be developed, and a new framework is needed to carry out the development of the new product. According to the suggestion of the front end supervisor, I am advised to carry out the transformation on the new framework he has developed, and the key points of the transformation are recorded here
Babel compiles compatible with IE
Add red code to the.babelrc file to prevent some ie methods from reporting errors
{
"env": {
"production": {
"only": [
"src",
"unicorn"
],
"plugins": [
"transform-react-remove-prop-types",
"transform-react-constant-elements",
"transform-react-inline-elements"
]
},
},
"plugins": [
[
"import",
{
"libraryName": "antd",
"libraryDirectory": "es",
"style": true
}
],
"transform-decorators-legacy",
"lodash"
],
"presets": [
[
"latest",
{
"es2015": {
"modules": false
}
}
],
"es2015-ie",
"react",
"stage-0"
]
}
Copy the code
Script run color
When NPM script is written as nodeJS script, the script color is gray, and the –color parameter is required
const shelljs = require('shelljs');
shelljs.exec('cross-env NODE_ENV=development node boot/internals/scripts/analyze.js --color', {
stdio: 'inherit',
});
Copy the code
Webpack speeds up builds
Add the hardsource-webpack-plugin to the webpack.base.babel.js file. After enabling the plugin, the build speed of the second time is shortened from 3040s to 35s
new HardSourceWebpackPlugin({
// Either an absolute path or relative to webpack's options.context.
cacheDirectory: path.resolve(process.cwd(), 'node_modules/.cache/hard-source/[confighash]'),
// Either a string of object hash function given a webpack config.
configHash(webpackConfig) {
// node-object-hash on npm can be used to build this.
return require('node-object-hash') ({sort: false }).hash({
webpackConfig,
globalVars,
});
},
// Either false, a string, an object, or a project hashing function.
environmentHash: {
root: process.cwd(),
directories: [].files: ['package-lock.json'.'yarn.lock'],},// An object.
info: {
// 'none' or 'test'.
mode: 'none'.// 'debug', 'log', 'info', 'warn', or 'error'.
level: 'debug',},// Clean up large, old caches automatically.
cachePrune: {
// Caches younger than `maxAge` are not considered for deletion. They must
// be at least this (default: 2 days) old in milliseconds.
maxAge: 2 * 24 * 60 * 60 * 1000.// All caches together must be larger than `sizeThreshold` before any
// caches will be deleted. Together they must be at least this
// (default: 50 MB) big in bytes.
sizeThreshold: 50 * 1024 * 1024,}}),// This will affect SVG generation, temporarily closed
// You can optionally exclude items that may not be working with HardSource
// or items with custom loaders while you are actively developing the
// loader.
// new HardSourceWebpackPlugin.ExcludeModulePlugin([
/ / {
// // HardSource works with mini-css-extract-plugin but due to how
// // mini-css emits assets, assets are not emitted on repeated builds with
// // mini-css and hard-source together. Ignoring the mini-css loader
// // modules, but not the other css loader modules, excludes the modules
// // that mini-css needs rebuilt to output assets every time.
// test: /mini-css-extract-plugin[\\/]dist[\\/]loader/,
/ /},
// ]),
Copy the code
The Webpack progress is abnormal
When NPM run build is executed, the simple-progress-webpack-plugin will constantly flush the screen, causing a bad experience, so it is only written in webpack.dev.babel.js for the time being
new SimpleProgressWebpackPlugin({
format: 'minimal',}).Copy the code
Lodash plugin optimization exception
Lodash. get cannot run properly after lodash-webpack-plugin is enabled. Add Paths: true
// Deep property path support for methods like _.get, _.has, & _.set.
// LoDash is optimized from 592.53K to 240K
new LodashModuleReplacementPlugin({
paths: true,}).Copy the code
The above update is updated at 2019-9-17 20:43:04
The react – loadable optimization
The withRef method failed
When react-loadable is applied to a function component, the withRef method will fail because the function component does not have a ref
import React from 'react'; import Loadable from 'react-loadable'; const LoaderCache = new Map(); export default function loadComponent(loader, options) { let component = LoaderCache.get(loader); if (! component) { component = Loadable({ loader, loading: (props) => { if (props.error) {// eslint-disable-line if (window.location.host.indexOf('-dev') >= 0 && window.TURKEY && window.TURKEY.getProperty('serverUpdate')) { window.TURKEY.run('serverUpdate'); } console.error('[chunk loader]', props.error); // eslint-disable-line } return <div />; }, render: (loaded, props) => { const Component = loaded.default; const { withRef, ... rest } = props; // eslint-disable-line const { isPureReactComponent, isReactComponent } = Component.prototype; let refProps = null; if (isPureReactComponent || isReactComponent) { refProps = { ref: (r) => { withRef && withRef(r); }}; } return (<Component {... refProps} {... rest} />); },... options, }); LoaderCache.set(loader, component); // component.preload(); } return component; }Copy the code
Stop setState
Because continuing the network request during component uninstallation will cause setState to report an error. Since the promise method is used and the request cannot be cancelled, setState needs to be null during uninstallation
The page level
/* eslint-disable no-param-reassign */ import React from 'react'; import Loadable from 'react-loadable'; const LoaderCache = new Map(); export default function loadComponent(loader, options) { let component = LoaderCache.get(loader); if (! component) { component = Loadable({ loader, loading: (props) => { if (props.error) {// eslint-disable-line if (window.location.host.indexOf('-dev') >= 0 && window.TURKEY && window.TURKEY.getProperty('serverUpdate')) { window.TURKEY.run('serverUpdate'); } console.error('[chunk loader]', props.error); // eslint-disable-line } return <div />; }, render: (loaded, props) => { const Component = loaded.default; const { withRef, ... rest } = props; // eslint-disable-line let refProps = null; // Only PureReactComponent and ReactComponent have a life cycle, Note in the case of the react - hook Component. The prototype is empty if (Component. The prototype && (Component. The prototype. IsPureReactComponent | | Component.prototype.isReactComponent)) { refProps = { ref: (r) => { withRef && withRef(r); if (! r) { return; } const cb = r.componentWillUnmount; r.componentWillUnmount = () => { r.setState = () => { // eslint-disable-next-line no-useless-return return; }; cb && cb.call(r); }; }}; } return (<Component {... refProps} {... rest} />); },... options, }); LoaderCache.set(loader, component); // component.preload(); } return component; }Copy the code
Component level
src\runtime\preventSetState.js
import React from 'react';
export default function preventSetState(WrappedComponent) {
return class Hoc extends React.PureComponent {
componentWillUnmount = () = > {
this.wrappedComponent.setState = () = > {
// eslint-disable-next-line no-useless-return
return;
};
}
render() {
return (<WrappedComponent
ref={(r)= >{ this.wrappedComponent = r; }} {... this.props} />); }}; }Copy the code
A call
import preventSetState from 'runtime/preventSetState';
@preventSetState
export default class Component extends React.PureComponent {}Copy the code
or
import preventSetState from 'runtime/preventSetState';
class Component extends React.PureComponent {}export default preventSetState(Component);
Copy the code
Functions to be expanded: React-hook to replace MOBx, Loading state or skeleton screen in HTML, dynamic polyfill, compilation to ES2015+ (to improve operation efficiency), LazyLoad, triparty library externalization
Reset error status
A single component error does not affect the loading of other pages
import React, { Component } from 'react'; import PropTypes from 'prop-types'; import styles from './styles.css'; class ErrorBoundary extends Component { state = { hasError: False,} componentWillReceiveProps () {/ / reset is not an error state this. SetState ({hasError: false,}); } componentDidCatch(error) { this.setState({ hasError: true, }); console.error(error); if (window.__bl) { window.__bl.error(error); }} render() {if (this.state.haserror) {return (<div className={styles.error}> <div className={styles.title}> Sorry, Page error! </div> </div> ); } return this.props.children; } } ErrorBoundary.propTypes = { children: PropTypes.node, }; export default ErrorBoundary;Copy the code
Stylelint invalid
package.json
"lint:css": "stylelint src/**/*.css"
Copy the code
When the above command is run on a MAC, it has no effect. Even if the CSS format is wrong, it is passed directly. At the same time, the error message before submitting the code has no color, which requires special treatment
"lint:css": "stylelint \"src/**/*.css\" --color" # SRC /**/*.css double quotes escape for Apple compatibility, --color is used to color error messages even before committing code by executing the pre-commit hook
"lint": "npm run lint:js && npm run lint:css"."pre-commit": "lint".Copy the code