ReactJS 测试文件问题'cannot find module'因为 webpack 模块解析器



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

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

您可以看到它的肮脏,不好。因此,我搜索了修复它,并找到了使用WebPack的解决方案。另外,我阅读了标题(配置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组件时,它说

无法从'foo.js'

找到模块'组件/foo'

示例测试文件。

foo.spec.js

    import React from 'react';
    import foo from 'components/foo';
    describe('(Component) foo', () => {
       it('should render foo', () => {
         expect(true).toBe(true);
       });
    });

这是第一个问题。我不能像这样导入foo。

注意:我的测试文件不在src文件夹中,它在test文件夹中。

所以我改变了这样的路径,然后才起作用。

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

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

foo.js

import bar from 'components/admin/bar';

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

无法从'foo.js'

找到模块'组件/admin/bar'

我将测试文件移入我的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文件中创建alias,然后从该别名导入,例如:

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

和您的文件中: import foo from '@app/components/foo'

这样,您就没有命名冲突,而您的道路也不错。

在我更改了package.json文件中的嘲笑对象后解决的问题。

"jest": {
  "moduleDirectories": [
     "node_modules",
     "src"
  ]
  ...

最新更新