webpack - Node模块包如何导入依赖?

标签 webpack material-ui node-modules babeljs yarnpkg

目前,在将 Material-UI 从 v0 迁移到 v3 的过程中,我面临多个文件从错误位置导入依赖项的问题。

我们以@babel/runtime依赖为例。

以下是我的package.json 和yarn.lock 文件的摘录:

"dependencies": {
  "@material-ui/core": "3.0.0",
  "@material-ui/icons": "3.0.0",
  "react-swipeable-views": "0.12.16",
  "react-swipeable-views-utils": "0.12.16",
},
"devDependencies": {
  "babel-cli": "6.26.0",
  "babel-core": "6.26.3",
  "babel-loader": "7.1.5",
  "babel-runtime": "6.26.0",
  "babel-regenerator-runtime": "6.5.0",
},
"@material-ui/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d8bbb7aabd98ebf6e8f6e8" rel="noreferrer noopener nofollow">[email protected]</a>":
  version "3.0.0"
  dependencies:
    "@babel/runtime" "7.0.0-rc.1"
"@material-ui/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f099939f9e83b0c3dec0dec0" rel="noreferrer noopener nofollow">[email protected]</a>":
  version "3.0.0"
  dependencies:
    "@babel/runtime" "7.0.0-rc.1"
react-event-listener@^0.6.0, react-event-listener@^0.6.2:
  version "0.6.3"
  dependencies:
    "@babel/runtime" "7.0.0-rc.1"
react-swipeable-views-core@^0.12.16:
  version "0.12.16"
  dependencies:
    "@babel/runtime" "7.0.0-beta.42"
recompose@^0.28.2:
  version "0.28.2"
  dependencies:
    "@babel/runtime" "7.0.0-beta.56"

@babel/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="285a5d465c41454d681f06180618054a4d5c49061c1a" rel="noreferrer noopener nofollow">[email protected]</a>":
  version "7.0.0-beta.42"
  dependencies:
    core-js "^2.5.3"
    regenerator-runtime "^0.11.1"
"@babel/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e89a9d869c81858da8dfc6d8c6d8c58a8d9c89c6ddde" rel="noreferrer noopener nofollow">[email protected]</a>":
  version "7.0.0-beta.56"
  dependencies:
    regenerator-runtime "^0.12.0"
"@babel/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="691b1c071d00040c295e47594759441b0a4758" rel="noreferrer noopener nofollow">[email protected]</a>":
  version "7.0.0-rc.1"
  dependencies:
    regenerator-runtime "^0.12.0"

还分享了我的 webpack 配置的一部分,因为我有预感它可能是罪魁祸首:

rules: [
  {
    test: /\.js$/,
    exclude: /node_modules/,
    loader: "babel-loader",
    query: {
      presets: [["es2015", {loose: true, modules: false}], "react", "stage-0"],
      plugins: ["transform-decorators-legacy"],
      cacheDirectory: true,
    },
  },
],
entry: [
  "babel-regenerator-runtime",
  path.resolve(__dirname, sourcePath, `${jsFilename}.js`),
],

还有我的 babelrc:

{
  "presets": [
    "es2015",
    "react",
    "stage-0",
    "flow"
  ],
  "plugins": [
    "transform-decorators-legacy",
    ["transform-runtime", {
      "polyfill": false,
      "regenerator": true
    }],
    ["babel-plugin-root-import", {
      "rootPathSuffix": "src"
    }]
  ]
}

我的所有 webpack 错误都涉及 @babel/runtime/helpers 目录中缺少 getPrototypeOf 文件:

ERROR in ./node_modules/@material-ui/core/styles/withTheme.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/getPrototypeOf' in '/project/node_modules/@material-ui/core/styles'    
 @ ./node_modules/@material-ui/core/styles/withTheme.js 20:46-94
 @ ./node_modules/@material-ui/core/styles/index.js
 @ ./src/components/Root.js
 @ ./src/app.js
 @ multi babel-regenerator-runtime ./src/app.js

ERROR in ./node_modules/react-event-listener/dist/react-event-listener.cjs.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/getPrototypeOf' in '/project/node_modules/react-event-listener/dist'   
 @ ./node_modules/react-event-listener/dist/react-event-listener.cjs.js 10:38-86
 @ ./node_modules/@material-ui/core/Popover/Popover.js
 @ ./node_modules/@material-ui/core/Popover/index.js
 @ ./src/components/Header/AnonymousMenu.js
 @ ./src/components/Header/index.js
 @ ./src/components/ListeningRoute.js
 @ ./src/components/Root.js
 @ ./src/app.js
 @ multi babel-regenerator-runtime ./src/app.js

如果我在node_modules中搜索该文件,除了根目录之外的所有目录都包含该文件:

$ for dir in $(find node_modules -name 'runtime'); do ls $dir/helpers/getPrototypeOf.js; done
node_modules/recompose/node_modules/@babel/runtime/helpers/getPrototypeOf.js
node_modules/@material-ui/icons/node_modules/@babel/runtime/helpers/getPrototypeOf.js
node_modules/@material-ui/core/node_modules/@babel/runtime/helpers/getPrototypeOf.js
node_modules/react-event-listener/node_modules/@babel/runtime/helpers/getPrototypeOf.js
ls: cannot access 'node_modules/@babel/runtime/helpers/getPrototypeOf.js': No such file or directory

节点模块应该递归地搜索依赖项,因此我们可以同时使用包的多个版本,而不会破坏项目,但在这种情况下,它们实际上是在根 node_modules/ 目录中搜索它们。

其他困惑来自于我们在项目中仍然使用 babel v6,但 @babel 安装在 project/node_modules 中。

有人可以解释为什么会发生这种行为吗?如果这是仅 yarn 问题,以及如何解决此问题?或者可能与 webpack 有关?

我希望在某个过渡时期拥有 Material-ui v0 和 v3 的并发版本,但当前的解决方案是硬迁移到 v3(以及将 babel 从 v6 迁移到 v7)。这确实阻碍了我们的迁移。

注意:cp node_modules/@material-ui/core/node_modules/@babel/runtime/helpers/getPrototypeOf.js node_modules/@babel/runtime/helpers 删除所有 webpack 错误...

最佳答案

在 webpack 中有一个名为“resolve”的选项。您必须设置解析选项,以便@material-ui 使用它们自己的node_modules。目前@material-ui 使用您通过npm 或yarn 安装的最上面的node_modules 导入依赖项。

在你的 webpack 配置中包含

module.exports = {
    ...

    resolve : {
        modules : ['node_modules']
    },

    ...
}

通过这样做,webpack 将查看相对目录中的 node_modules

关于webpack - Node模块包如何导入依赖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52053561/

相关文章:

javascript - 使用 webpack 为捆绑代码添加样式

reactjs - Enzyme/Karma/Webpack/Jasmine/React 测试不起作用

webpack - 如何动态创建一个应包含在 webpack bundle 中的新文件?

reactjs - 设置 Material UI 动态响应 TableCell 宽度

javascript - 使用不同的 props React ES6 渲染多个项目

node.js - 如何在公共(public)网络服务器上为 Node 应用程序安装 Node 模块?

docker - docker 容器的 webpack-dev-server 代理

css - Material-UI 内联样式 SEO 影响

node.js - 在 Node 中使用 128 位长(uuid)还是 7 位长(shortid)唯一 ID 生成器更好?

angular - 指定要在 Angular 中使用的 NPM 模块平台