我正在开发带有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"
]
...