如何在 Webpack 中将 @material-ui/core 指定为外部?

How does one specify @material-ui/core as an external in Webpack?

我将 React 组件发布为独立的 npmjs 包。我的 React 组件依赖 @material-ui/core 作为依赖项。我可以在我的 Webpack 配置文件中将 reactreact-router-dom 包指定为外部包,但似乎 @material-ui/core 仍然捆绑到我的最终产品中而不是外部包。

webpack.config.js:

externals: {
  '@material-ui/core': {
    amd: '@material-ui/core',
    commonjs: '@material-ui/core',
    commonjs2: '@material-ui/core'
  },
  'react': {
    amd: 'react',
    commonjs: 'react',
    commonjs2: 'react',
    root: 'React'
  },
  'react-router-dom': {
    amd: 'react-router-dom',
    commonjs: 'react-router-dom',
    commonjs2: 'react-router-dom'
  }
},
output: {
  filename: 'index.js',
  libraryTarget: 'umd',
  path: path.resolve(__dirname, 'build'),
  umdNamedDefine: true
},
resolve: {
  alias: {
    '@material-ui/core': path.resolve(__dirname, './node_modules/@material-ui/core'),
    'react': path.resolve(__dirname, './node_modules/react'),
    'react-router-dom': path.resolve(__dirname, './node_modules/react-router-dom')
  }
}

最终的捆绑包有:

module.exports=t(require("react"),require("react-router-dom"));

但是没有require("@material-ui/core")。相反,Material UI 包似乎包含在包本身中,使其变得不必要地大。

webpack --display-modules 的输出:

Hash: 1d2c07fff1122c1bfe92
Version: webpack 4.6.0
Time: 6030ms
Built at: 2018-07-12 11:36:08
  Asset      Size  Chunks             Chunk Names
index.js  93.4 KiB       0  [emitted]  main
Entrypoint main = index.js
  [0] ./node_modules/@babel/runtime/helpers/builtin/interopRequireDefault.js 145 bytes {0} [built]
  [1] ./node_modules/@babel/runtime/helpers/builtin/objectSpread.js 623 bytes {0} [built]
  [2] ./node_modules/warning/warning.js 1.76 KiB {0} [built]
  [3] external {"amd":"react","commonjs":"react","commonjs2":"react","root":"React"} 42 bytes {0} [built]
  [4] ./node_modules/@babel/runtime/helpers/builtin/objectWithoutProperties.js 665 bytes {0} [built]
  [5] ./node_modules/prop-types/index.js 956 bytes {0} [built]
  [6] ./node_modules/jss/lib/rules/StyleRule.js 5.32 KiB {0} [built]
  [7] ./node_modules/jss/node_modules/warning/browser.js 1.76 KiB {0} [built]
  [8] ./node_modules/@babel/runtime/helpers/builtin/defineProperty.js 289 bytes {0} [built]
  [9] ./node_modules/jss/lib/RuleList.js 6.4 KiB {0} [built]
[10] ./node_modules/@material-ui/core/styles/withStyles.js 13.6 KiB {0} [built]
[11] ./node_modules/is-in-browser/dist/module.js 510 bytes {0} [built]
[12] ./node_modules/jss/lib/utils/createRule.js 1.08 KiB {0} [built]
[13] ./node_modules/jss/lib/utils/toCssValue.js 1.33 KiB {0} [built]
[14] ./node_modules/deepmerge/dist/es.js 2.57 KiB {0} [built]
[15] ./node_modules/@material-ui/core/styles/createMuiTheme.js 2.93 KiB {0} [built]
[16] (webpack)/buildin/global.js 489 bytes {0} [built]
[17] ./node_modules/@babel/runtime/helpers/builtin/inherits.js 505 bytes {0} [built]
[18] ./node_modules/@babel/runtime/helpers/builtin/possibleConstructorReturn.js 354 bytes {0} [built]
[19] ./node_modules/@babel/runtime/helpers/builtin/createClass.js 596 bytes {0} [built]
[20] ./node_modules/@babel/runtime/helpers/builtin/classCallCheck.js 196 bytes {0} [built]
[21] ./node_modules/recompose/getDisplayName.js 353 bytes {0} [built]
[22] ./node_modules/@babel/runtime/helpers/builtin/extends.js 427 bytes {0} [built]
[23] ./node_modules/@material-ui/core/styles/themeListener.js 1.06 KiB {0} [built]
[24] ./node_modules/css-vendor/lib/prefix.js 1.14 KiB {0} [built]
[25] ./node_modules/jss/lib/sheets.js 649 bytes {0} [built]
[26] ./node_modules/jss/lib/utils/toCss.js 2.11 KiB {0} [built]
[27] ./node_modules/@babel/runtime/helpers/builtin/typeof.js 817 bytes {0} [built]
[28] ./node_modules/react-jss/lib/ns.js 426 bytes {0} [built]
[29] ./node_modules/recompose/wrapDisplayName.js 483 bytes {0} [built]
[30] ./node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js 2.02 KiB {0} [built]
[31] ./node_modules/@material-ui/core/utils/exactProp.js 1.44 KiB {0} [built]
[32] ./node_modules/@babel/runtime/helpers/builtin/interopRequireWildcard.js 640 bytes {0} [built]
[33] ./node_modules/@material-ui/core/styles/MuiThemeProvider.js 6.93 KiB {0} [built]
[34] ./node_modules/jss/lib/StyleSheet.js 6.08 KiB {0} [built]
[35] ./node_modules/jss/lib/utils/createGenerateClassName.js 1.46 KiB {0} [built]
[36] ./node_modules/jss/lib/utils/linkRule.js 356 bytes {0} [built]
[37] ./node_modules/jss/lib/utils/isObservable.js 454 bytes {0} [built]
[38] ./node_modules/jss/lib/SheetsRegistry.js 2.46 KiB {0} [built]
[39] ./node_modules/jss/lib/index.js 2.12 KiB {0} [built]
[40] ./node_modules/@material-ui/core/styles/jssPreset.js 1020 bytes {0} [built]
[41] ./node_modules/@material-ui/core/styles/createGenerateClassName.js 3.69 KiB {0} [built]
[42] ./node_modules/jss/node_modules/symbol-observable/es/ponyfill.js 333 bytes {0} [built]
[43] ./src/constants/theme.js 913 bytes {0} [built]
[44] ./src/components/footer/link/footer-link-styles.js 189 bytes {0} [built]
[45] ./src/components/footer/link/footer-link.js 2.67 KiB {0} [built]
[46] ./src/components/footer/footer-styles.js 244 bytes {0} [built]
[47] ./node_modules/@material-ui/core/utils/helpers.js 2.34 KiB {0} [built]
[48] ./node_modules/classnames/index.js 1.17 KiB {0} [built]
[49] ./node_modules/@material-ui/core/Typography/Typography.js 5.81 KiB {0} [built]
[50] ./node_modules/@material-ui/core/Typography/index.js 370 bytes {0} [built]
[51] ./src/components/footer/footer.js 4.3 KiB {0} [built]
[52] ./node_modules/style-loader/lib/urls.js 2.94 KiB {0} [built]
[53] ./node_modules/style-loader/lib/addStyles.js 9.77 KiB {0} [built]
[54] ./node_modules/css-loader/lib/css-base.js 2.21 KiB {0} [built]
[55] ./node_modules/css-loader!./src/assets/index.css 758 bytes {0} [built]
[56] ./src/assets/index.css 1.06 KiB {0} [built]
[57] external {"amd":"react-router-dom","commonjs":"react-router-dom","commonjs2":"react-router-dom"} 42 bytes {0} [built]
[58] ./node_modules/@material-ui/core/styles/withTheme.js 3.38 KiB {0} [built]
[59] ./node_modules/@material-ui/core/styles/getThemeProps.js 356 bytes {0} [built]
[60] ./node_modules/@material-ui/core/styles/getStylesCreator.js 2.01 KiB {0} [built]
[61] ./node_modules/@material-ui/core/styles/mergeClasses.js 1.87 KiB {0} [built]
[62] ./node_modules/react-jss/lib/propTypes.js 516 bytes {0} [built]
[63] ./node_modules/react-jss/lib/contextTypes.js 1.26 KiB {0} [built]
[64] ./node_modules/@material-ui/core/styles/createStyles.js 153 bytes {0} [built]
[65] ./node_modules/brcast/dist/brcast.es.js 1010 bytes {0} [built]
[66] ./node_modules/jss-props-sort/lib/index.js 566 bytes {0} [built]
[67] ./node_modules/css-vendor/lib/supported-value.js 1.82 KiB {0} [built]
[68] ./node_modules/css-vendor/lib/camelize.js 376 bytes {0} [built]
[69] ./node_modules/css-vendor/lib/supported-property.js 2 KiB {0} [built]
[70] ./node_modules/css-vendor/lib/index.js 1.07 KiB {0} [built]
[71] ./node_modules/jss-vendor-prefixer/lib/index.js 1.59 KiB {0} [built]
[72] ./node_modules/jss-default-unit/lib/defaultUnits.js 2.81 KiB {0} [built]
[73] ./node_modules/jss-default-unit/lib/index.js 2.72 KiB {0} [built]
[74] ./node_modules/hyphenate-style-name/index.js 339 bytes {0} [built]
[75] ./node_modules/jss-camel-case/lib/index.js 1.66 KiB {0} [built]
[76] ./node_modules/jss-nested/node_modules/warning/browser.js 1.76 KiB {0} [built]
[77] ./node_modules/jss-nested/lib/index.js 3.44 KiB {0} [built]
[78] ./node_modules/jss/lib/renderers/VirtualRenderer.js 2.1 KiB {0} [built]
[79] ./node_modules/jss/lib/renderers/DomRenderer.js 12.1 KiB {0} [built]
[80] ./node_modules/jss/lib/plugins/functions.js 1.94 KiB {0} [built]
[81] ./node_modules/jss/lib/plugins/observables.js 1.67 KiB {0} [built]
[82] ./node_modules/jss/lib/rules/ViewportRule.js 1.49 KiB {0} [built]
[83] ./node_modules/jss/lib/rules/FontFaceRule.js 1.77 KiB {0} [built]
[84] ./node_modules/jss/lib/rules/ConditionalRule.js 2.68 KiB {0} [built]
[85] ./node_modules/jss/lib/rules/KeyframesRule.js 2.19 KiB {0} [built]
[86] ./node_modules/jss/lib/rules/SimpleRule.js 1.59 KiB {0} [built]
[87] ./node_modules/jss/lib/plugins/rules.js 1.6 KiB {0} [built]
[88] ./node_modules/jss/lib/PluginsRegistry.js 3.75 KiB {0} [built]
[89] ./node_modules/jss/lib/Jss.js 7.05 KiB {0} [built]
[90] ./node_modules/jss/lib/utils/moduleId.js 466 bytes {0} [built]
[91] ./node_modules/jss/lib/utils/escape.js 512 bytes {0} [built]
[92] (webpack)/buildin/harmony-module.js 573 bytes {0} [built]
[93] ./node_modules/jss/node_modules/symbol-observable/es/index.js 403 bytes {0} [built]
[94] ./node_modules/jss/lib/utils/cloneStyle.js 1.49 KiB {0} [built]
[95] ./node_modules/jss/lib/SheetsManager.js 2.62 KiB {0} [built]
[96] ./node_modules/jss/lib/utils/getDynamicStyles.js 976 bytes {0} [built]
[97] ./node_modules/jss-global/lib/index.js 4.82 KiB {0} [built]
[98] ./node_modules/@material-ui/core/styles/zIndex.js 377 bytes {0} [built]
[99] ./node_modules/@material-ui/core/styles/transitions.js 4.62 KiB {0} [built]
[100] ./node_modules/@material-ui/core/styles/spacing.js 355 bytes {0} [built]
[101] ./node_modules/@material-ui/core/styles/shape.js 190 bytes {0} [built]
[102] ./node_modules/@material-ui/core/styles/shadows.js 2.51 KiB {0} [built]
[103] ./node_modules/@material-ui/core/styles/createTypography.js 4.92 KiB {0} [built]
[104] ./node_modules/@material-ui/core/styles/colorManipulator.js 8.12 KiB {0} [built]
[105] ./node_modules/@material-ui/core/colors/common.js 207 bytes {0} [built]
[106] ./node_modules/@material-ui/core/colors/red.js 422 bytes {0} [built]
[107] ./node_modules/@material-ui/core/colors/grey.js 424 bytes {0} [built]
[108] ./node_modules/@material-ui/core/colors/pink.js 424 bytes {0} [built]
[109] ./node_modules/@material-ui/core/colors/indigo.js 428 bytes {0} [built]
[110] ./node_modules/@material-ui/core/styles/createPalette.js 7.24 KiB {0} [built]
[111] ./node_modules/@material-ui/core/styles/createMixins.js 1.28 KiB {0} [built]
[112] ./node_modules/@material-ui/core/styles/createBreakpoints.js 2.33 KiB {0} [built]
[113] ./node_modules/@babel/runtime/helpers/builtin/objectWithoutPropertiesLoose.js 384 bytes {0} [built]
[114] ./node_modules/@material-ui/core/styles/index.js 1.62 KiB {0} [built]
[115] ./node_modules/prop-types/lib/ReactPropTypesSecret.js 314 bytes {0} [built]
[116] ./node_modules/prop-types/factoryWithThrowingShims.js 1.43 KiB {0} [built]
[117] ./node_modules/@babel/runtime/helpers/builtin/setPrototypeOf.js 237 bytes {0} [built]
[118] ./node_modules/@babel/runtime/helpers/builtin/assertThisInitialized.js 219 bytes {0} [built]
[119] ./node_modules/@material-ui/core/CssBaseline/CssBaseline.js 2.71 KiB {0} [built]
[120] ./node_modules/@material-ui/core/CssBaseline/index.js 373 bytes {0} [built]
[121] (webpack)/node_modules/process/browser.js 5.29 KiB {0} [built]
[122] ./src/index.js 3.39 KiB {0} [built]

引用 @material-ui/core 作为正则表达式而不是字符串。 /^\@material\-ui\/core\/.*/ 以匹配所有以相关命名空间开头的导入。

对我有用的正则表达式:

externals: [ /^@material-ui\/(core|icons)[\/a-zA-Z]*/ ]
  • 导入样式为:import { Card } from '@material-ui/core',看别人的回答。

  • 使用样式导入:import Card from '@material-ui/core/Card',见下文:

externals: [
  externalForMaterialUi
]

function externalForMaterialUi(context, request, callback) {
  if (/@material-ui.+/.test(request)) {
    const name = request.replace(/^.*[\\/]/, '')
    return callback(null, 'root MaterialUI.' + name);
  }
  callback();
}

umd cdn。 webpack 4.41.2, @material-ui/core 4.7.2