javascript - 由于 webpack 模块解析器而导致 ReactJS 测试文件问题 'cannot find module'

标签 javascript reactjs ecmascript-6 webpack-2 babeljs

我正在使用react.js 开发一个应用程序。我的应用程序正在成长。所以我在进口方面没有遇到什么麻烦。例如,我有一个名为 foo 的组件,我在很多地方使用它。

import foo from '../../components/foo';
import foo from '../components/foo';
import foo from '../../../components/foo';

如您所见,它很脏,不好。所以我搜索修复它,并找到了 webpack 的解决方案。我还阅读了此 article 中的标题(配置 Webpack 的模块分辨率以避免嵌套导入)

我将此代码添加到我的 webpack.config.js 文件中

modules: [
     'node_modules',
     path.resolve(__dirname, 'src')
  ]

所以我的解析对象看起来像这样

export default {
resolve: {
  modules: [
     'node_modules',
     path.resolve(__dirname, 'src')
  ],
  extensions: ['*', '.js', '.jsx', '.json']
},
...

之后我就可以在像这样的任何地方使用导入我的 foo 组件。

import foo from 'components/foo';

到目前为止一切都还好。但问题出现在测试文件中。

当我尝试测试 foo 组件时,它说

Cannot find module 'components/foo' from 'foo.js'

示例测试文件。

foo.spec.js

    import React from 'react';
    import foo from 'components/foo';

    describe('(Component) foo', () => {
       it('should render foo', () => {
         expect(true).toBe(true);
       });
    });

这是第一个问题。我无法像这样导入 foo。

Note: My test file is not in src folder it is in the test folder.

所以我像这样改变了路径,然后它就起作用了。

import foo from '../../../src/components/foo';

泰斯通过了,一切看起来都很好。但我们的测试文件仍然存在路径问题。 让我们尝试在 foo 组件中导入另一个组件。

foo.js

import bar from 'components/admin/bar';

这是第二个问题。测试文件失败错误消息为

Cannot find module 'components/admin/bar' from 'foo.js'

我将测试文件移至 foo.js 文件中。但没有成功。

这是我的整个webpack.config.js

import webpack from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import autoprefixer from 'autoprefixer';
import path from 'path';
export default {
   resolve: {
      modules: [
         'node_modules',
         path.resolve(__dirname, 'src')
      ],
      extensions: ['*', '.js', '.jsx', '.json']
   },
   devtool: 'inline-source-map', // more info:https://webpack.github.io/docs/build-performance.html#sourcemaps and https://webpack.github.io/docs/configuration.html#devtool
   entry: [
      // must be first entry to properly set public path
      './src/webpack-public-path',
      'webpack-hot-middleware/client?reload=true',
      path.resolve(__dirname, 'src/index.js') // Defining path seems necessary for this to work consistently on Windows machines.
   ],
   target: 'web', // necessary per https://webpack.github.io/docs/testing.html#compile-and-test
   output: {
      path: path.resolve(__dirname, 'dist'), // Note: Physical files are only output by the production build task `npm run build`.
      publicPath: '/',
      filename: 'bundle.js'
   },
   plugins: [
      new webpack.DefinePlugin({
         'process.env.NODE_ENV': JSON.stringify('development'), // Tells React to build in either dev or prod modes. https://facebook.github.io/react/downloads.html (See bottom)
         __DEV__: true,
         //'API_URL': API_URL.dev
      }),
      new webpack.HotModuleReplacementPlugin(),
      new webpack.NoEmitOnErrorsPlugin(),
      new HtmlWebpackPlugin({     // Create HTML file that includes references to bundled CSS and JS.
         template: 'src/index.ejs',
         minify: {
            removeComments: true,
            collapseWhitespace: true
         },
         inject: true
      }),
      new webpack.LoaderOptionsPlugin({
         minimize: false,
         debug: true,
         noInfo: true, // set to false to see a list of every file being bundled.
         options: {
            sassLoader: {
               includePaths: [path.resolve(__dirname, 'src', 'scss')]
            },
            context: '/',
            postcss: () => [autoprefixer],
         }
      })
   ],
   module: {
      rules: [
         {test: /\.jsx?$/, exclude: /node_modules/, loaders: ['babel-loader']},
         {test: /\.eot(\?v=\d+.\d+.\d+)?$/, loader: 'file-loader'},
         {
            test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
            loader: 'url-loader?limit=10000&mimetype=application/font-woff'
         },
         {test: /\.[ot]tf(\?v=\d+.\d+.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'},
         {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml'},
         {test: /\.(jpe?g|png|gif)$/i, loader: 'file-loader?name=[name].[ext]'},
         {test: /\.ico$/, loader: 'file-loader?name=[name].[ext]'},
         {
            test: /(\.css|\.scss|\.sass)$/,
            loaders: ['style-loader', 'css-loader?sourceMap', 'postcss-loader', 'sass-loader?sourceMap']
         }
      ]
   }
};

如何解决? 感谢您的帮助。

最佳答案

测试执行期间不使用Webpack。由于您使用的是 babel babel-plugin-module-resolver https://github.com/tleunen/babel-plugin-module-resolver应该可以解决问题:

在你的.babelrc文件中

{
  "plugins": [
    ["module-resolver", {
      "root": ["./src"]
    }]
  ]
}

更简洁的方法是在 .babelrc 文件中创建一个别名,然后从该别名导入,例如:

{
    "plugins": [
        ["module-resolver", {
            "alias": {
                "@app": "./src"
            }
        }]
    ]
}

在你的文件中: 从“@app/components/foo”导入 foo

这样您就不会出现命名冲突,并且您的路径又好又短。

关于javascript - 由于 webpack 模块解析器而导致 ReactJS 测试文件问题 'cannot find module',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43754466/

相关文章:

javascript - 这里的setState回调语法有什么区别?

javascript - 将 jQuery 事件处理程序附加到 dom 元素的正确方法是什么?什么将被重复替换?

javascript - 如何提交从 typeahead bloodhound 自动完成填充的数据

javascript - Vaadin 8 Html 导入 Javascript

reactjs - 为什么这个aureliaJS-reactJS示例中有一个名为bind()的函数?

ReactJS:显示模态和重新渲染

javascript - 从元素属性值初始化 Knockout observable

javascript - 在 React 中将 .map() 助手与 Bootstrap <Col sm ="4"/> 布局一起使用

javascript - 数组数组与 Lodash 的比较

javascript - 如何从两个库导入两个相同名称的组件?