如果文件名为jsx,webpack找不到模块

138

当我像这样编写webpack.config.js文件时

module.exports = {
  entry: './index.jsx',
  output: {
    filename: 'bundle.js'
  },
  module: {
    loaders: [{
      test: /\.jsx?$/,
      exclude: /node_modules/,
      loader: 'babel',
      query: {
        presets: ['es2015', 'react']
      }
    }]
  }
};

index.jsx 中,我导入了一个名为 Appreact 模块。

import React from 'react';
import { render } from 'react-dom';

import App from './containers/App';

let rootElement = document.getElementById('box')
render(
  <App />,
  rootElement
)

我发现如果在App.jsx中将模块命名为 app,那么webpack会在index.jsx中报错,无法找到模块App,但是如果我在App.js中命名为 app,它将能找到此模块并正常工作。

所以,我很困惑。在我的webpack.config.js中,我已经写了test: /\.jsx?$/来检查文件,但为什么命名为*.jsx的模块会找不到呢?

enter image description here

8个回答

254

Webpack默认不能隐式解析.jsx文件。您可以在应用程序中指定文件扩展名(import App from './containers/App.jsx';)。当前的loader测试表示当您显式导入带有jsx扩展名的文件时使用babel loader。

或者,您可以将.jsx包含在Webpack应该无需显式声明即可解析的扩展名列表中:

module.exports = {
  entry: './index.jsx',
  output: {
    filename: 'bundle.js'
  },
  module: {
    loaders: [{
      test: /\.jsx?$/,
      exclude: /node_modules/,
      loader: 'babel',
      query: {
        presets: ['es2015', 'react']
      }
    }]
  },
  resolve: {
    extensions: ['', '.js', '.jsx'],
  }
};

对于 Webpack 2,不要使用空扩展名。

resolve: {
  extensions: ['.js', '.jsx']
}

76
对于 webpack 4,我发现需要在 module 下列出的 rule 中的一个中加入以下内容:{ test: /\.jsx?$/, resolve: { extensions: [".js", ".jsx"] }, include: ... }其中 include 需要根据具体情况进行填写。 - mr rogers
1
@mrrogers 我到处搜索了这个!我向您致敬! - Frederik Petersen
1
非常感谢!我已经寻找了好几个小时了! - KevinH
2
@mrrogers 考虑将您的评论提升为答案 :) - Alexander Varwijk
谢谢@AlexanderVarwijk。好主意。我自己也回到这些评论中去记住我必须做的事情 :) - mr rogers
1
@mrrogers 谢谢!这个解决方案也适用于webpack 5! - C-Dev

46

为了易读性和复制粘贴编码的方便,以下是webpack 4的答案,来自mr rogers在该主题中的评论。

module: {
  rules: [
    {
      test: /\.(js|jsx)$/,
      exclude: /node_modules/,
      resolve: {
        extensions: [".js", ".jsx"]
      },
      use: {
        loader: "babel-loader"
      }
    },
  ]
}

1
准确来说是从4.36.1版本开始。这里是文档链接:https://webpack.js.org/configuration/module/#ruleresolve - Alexey Berezkin

29

在上面的回答中补充一点:

resolve 属性是您必须添加应用程序中使用的所有文件类型的位置。

假设您想要使用.jsx或.es6文件,您可以将它们包含在此处,webpack将解析它们:

resolve: {
  extensions: ["", ".js", ".jsx", ".es6"]
}

如果您在resolve属性中添加扩展名,就可以从导入语句中删除它们:

import Hello from './hello'; // Extensions removed
import World from './world';

如果你想让 CoffeeScript 被检测到,你需要像这样配置你的 test 属性:

// webpack.config.js
module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js'       
  },
  module: {
    loaders: [
      { test: /\.coffee$/, loader: 'coffee-loader' },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015', 'react']
        }
      }
    ]
  },
  resolve: {
    // you can now require('file') instead of require('file.coffee')
    extensions: ['', '.js', '.json', '.coffee'] 
  }
};

10
在 WebPack 3.4 中,你不能使用值为空的 resolve.extension。这将导致编译时出现异常:“配置对象无效。Webpack 已经初始化了一个与 API 模式不匹配的配置对象。
  • 配置.resolve.extensions[0] 不应为空。”
- Julio Spader

14

如 @max 的回答评论中提到的,对于 webpack 4,我发现需要将以下内容放在列在 module 下的规则之一中:

{
  module: {
    rules: [ 
      {
        test: /\.jsx?$/, 
        resolve: {
          extensions: [".js", ".jsx"]
        },
        include: ...
      }
    ]
  }
}

2

请验证bundle.js是否已经生成且没有错误(检查任务运行器日志)。

我在组件渲染函数中的html语法错误导致出现“找不到名为jsx的模块”。


2

在构建我的TypeScript项目时,我遇到了与导入相关的类似问题,该项目具有以下webpack依赖项:

"webpack": "^5.28.0",
"webpack-cli": "^4.5.0" 

所以,我在正确的路径下有一个名为App.tsx的文件,并进行了命名导出。但是,yarn build失败并显示错误信息Module not found: Error: Can't resolve './App' in '/app/sample_proj/src'。与此错误相关的代码为:import {App} from './App';。为了解决这个问题,我需要在webpack已知扩展名中添加.tsx。在webpack.config.js文件中添加示例条目如下:

 module.exports = {
       ......
       resolve: {
            extensions: [ '.ts', '.js', '.tsx', '.jsx'],
        }
     }

此外,对于这个错误,无论是默认导入还是命名导入都没关系。webpack 只需要知道它应该处理哪种文件扩展名。

1

我遇到了类似的问题,使用 resolve 属性解决了问题。

const path = require('path');
module.exports = {
    entry: './src/app.jsx',
    output: {
        path: path.join(__dirname,'public'),
        filename:  'bundle.js'
    },
    module : {
        rules: [{
            loader: 'babel-loader',
            test: /\.jsx$/,
            exclude: /node_modules/
        }]
    },
    resolve: {
        extensions: ['.js', '.jsx']
    }
}

如您所见,我在其中使用了.jsx,解决了以下错误

ERROR in ./src/app.jsx Module not found: Error: Can't resolve

参考资料:https://webpack.js.org/configuration/resolve/#resolve-extensions


-5

我发现重新启动我的服务器可以解决这个问题。只需运行

npm start

1
尽管重新启动服务器应该是首选的,但这只是重新启动服务器,而不是解决当前的问题。 - Brittan McGinnis
事实上,这个解决方案解决了我的问题。对于一个 create-react-app 应用程序而言,如果不能更改 webpack 代码,那么这就是解决方案。 - Leonidas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接