使用 Webpack 外部组件并仍然允许 ES6 样式导入?

Kev*_*vin 5 javascript google-chrome-extension reactjs webpack

我正在创建一个 Chrome 扩展,并且正在使用 React 和 Webpack。

因为这是一个 Chrome 扩展,所以我可以manifest.json在执行我自己的代码的任何行之前将 React 和 ReactDOM 加载到浏览器中。我的理解是:

  • 加载的react.js库manifest.json显示为全局变量,可通过window.React访问
  • 可以配置 webpack 外部,以便 React 和 ReactDOM 不会被捆绑

这是我的文件:

webpack.config.js

module.exports = {

  entry: './index.js',
  output: {
    filename: 'skinny-bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      }
    ]
  },

  externals: {
    react: {
      root: 'React',
      commonjs2: 'react',
      commonjs: 'react',
      amd: 'react'
    },
    'react-dom': {
      root: 'reactDOM'
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

清单.json

{
  "manifest_version": 2,
  "name": "Test Application",
  "version": "3.2",
  "description": "testing",
  "short_name": "some test",

  "author": "blah blah",

  "content_scripts": [
     {
       "matches": ["https://www.google.com/*"],
       "js": [
         "react.js",
         "react-dom.js",

         "skinny-bundle.js"
       ],
       "run_at": "document_idle"
     }
   ]
}
Run Code Online (Sandbox Code Playgroud)

索引.js

import HelloGreeting from './HelloGreeting'    

ReactDOM.render(
    <HelloGreeting />,
    document.getElementById('cst')
)
Run Code Online (Sandbox Code Playgroud)

HelloGreeting.js

// import React from 'react'   <----- here is my problem!!!

// functional component test
const Hello = props => {
  return (
    <div>hello world</div>
  )
}

// class component test
class HelloGreeting extends React.Component {
  constructor(props) {
    super(props)
  }

  render() {
    return (
      <ul>
        <li><Hello /></li>
        <li>hello universe</li>
      </ul>
    )
  }
}

export default HelloGreeting
Run Code Online (Sandbox Code Playgroud)

我的问题就在这里。我有一个名为 HelloGreeting 的简单 React 组件,如果我保留线路,它就不起作用import React from 'react'。如果我注释掉导入,它实际上会起作用,因为我的猜测是 webpack 只是忽略它,因为 React 已经在 webpack 外部中定义了。如果我将 import 语句留在 中,我会收到错误"Uncaught TypeError: Cannot read property 'Component' if undefined",可能是因为 Webpack 试图以某种方式捆绑并搞乱 window.React。我做出这个猜测是因为 webpack 在有或没有导入的情况下会发出什么。

如果我注释掉导入,webpack 会发出一个更小的包:

Hash: 26f1526e2554c828c050
Version: webpack 3.5.5
Time: 80ms
           Asset     Size  Chunks             Chunk Names
skinny-bundle.js  5.75 kB       0  [emitted]  main
   [1] ./HelloGreeting.js 2.5 kB {0} [built]
    + 1 hidden module
Run Code Online (Sandbox Code Playgroud)

如果我保留导入,我的 webpack 会发出一个更大的包:

Hash: 1fc9353f1fe6dd935744
Version: webpack 3.5.5
Time: 77ms
           Asset     Size  Chunks             Chunk Names
skinny-bundle.js  6.05 kB       0  [emitted]  main
   [1] ./HelloGreeting.js 2.71 kB {0} [built]
    + 2 hidden modules
Run Code Online (Sandbox Code Playgroud)

我的问题是,我可以做什么来配置 webpack,以便我仍然拥有 ES6 样式导入,并且仍然拥有 webpack 而不是捆绑 React.js?

我真的很想保留导入语句,因为这些组件将在未来的项目中使用,并且我希望尽可能保持模块化和可移植性。

Kev*_*vin 5

事实证明我的 webpack 过于复杂化了externals

更改自:

externals: {
    react: {
      root: 'React',
      commonjs2: 'react',
      commonjs: 'react',
      amd: 'react'
    },
    'react-dom': {
      root: 'reactDOM'
    }
  }
Run Code Online (Sandbox Code Playgroud)

到:

externals: {
    react: 'React',
    'react-dom': 'ReactDOM'
  },
Run Code Online (Sandbox Code Playgroud)

...解决了我的问题。现在,webpack 会忽略我所有的 React 代码并保持我的包很小。

https://github.com/webpack/webpack/issues/1275帮助了我。