在使用Webpack、Typescript和自定义模块目录时找不到模块。

7

我想要做什么

我编写了一个虚拟模块my-component,它基本上导出一个单一的类Something。我将其放置在app/modules/中。现在我正在尝试使用从app/app.js导入语法访问它:

import { Something } from 'my-component';

期望结果:根据我当前的Webpack配置(如下),我希望它能正常工作。

实际结果:但是会抛出以下错误:

ERROR in [default] /<project_dir>/app/app.ts:1:26
Cannot find module 'my-component/Something'.

我尝试修复的问题

我知道这个模块本身是正确定义的,因为:

  1. 我可以使用相对路径导入它:import { Something } from './my-component'
  2. 如果我将该模块移动到 node_modules/my-component,我也可以直接导入它。

唯一失败的组合是从modules/ 目录下无相对路径导入它。因此,我认为问题可能出在我的 Webpack 配置上。

设置详情

如下所示,我列出了两个目录作为resolve.root

  • project_dir/app
  • project_dir/node_modules

看起来,它好像能够从 node_modules 解析,但却不能从 app 解析。

项目布局

                               Webpack
project_dir/
 ├── app/                      context, resolve.root
 │    ├── app.ts
 │    └── my-component/
 │         ├── index.ts
 │         └── Something.ts
 ├── webpack.config.js
 ├── node_modules/             resolve.root
 │    ├── ...
 │    ├── ...
 │    └── ...
 └── dist/
      └── ...

app/app.ts

import { Something } from 'my-component/Something';

app/my-component/index.ts

export { Something } from './Something'

app/my-component/Something.ts

class Something {
}

export { Something };

webpack.config.js

var path = require('path'),
  ROOT = path.resolve(__dirname, '.');

module.exports = {
  context: path.resolve(ROOT, 'app'),
  entry: 'app.ts',
  output: {
    path: path.resolve(ROOT, 'dist'),
    filename: '[name]-[hash].js'
  },
  module: {
    loaders: [
      { test: /\.ts$/, loader: 'awesome-typescript' }
    ]
  },
  resolve: {
    root: [
      path.resolve(__dirname, 'app'),
      path.resolve(__dirname, 'node_modules')
    ],
    extensions: [
      '', '.ts', '.js'
    ]
  }
};

编辑 已修正项目布局。


不确定这是否相关,只是一条评论:您尝试过在app.ts中使用import { Something } from './my-component/Something';吗?相对路径必须以./开头,等等。如果没有,则假定为“node_modules”。 - Jason Kleban
3个回答

15

找不到模块

如果您在使用 ESNEXT 进行动态模块加载时遇到此问题,

您需要在您的 tsconfig.json 文件中添加 "moduleResolution": "node"


6
我发现了一个比之前被接受的更简单的解决方案:
在你的 TypeScript 配置中,设置 compilerOptions 中的 baseUrltsconfig.json
{
  "compilerOptions": {
    "baseUrl": "./app",
    ...
  },
  ...
}

解释:

Webpack和Typescript默认使用节点模块解析,这是可以的。 但是,在设置自定义模块文件夹时,您需要在Webpack和Typescript配置中都进行配置。 对Webpack模块解析配置的更改不会传播到Typescript编译器。


2

好的。我创建了一个与您项目结构相同的副本。似乎情况是import语句的行为不像require那样,并且webpack的resolve.root配置能够按预期工作。

对于模块,请将您的import语句更改为以下形式的require:

app.ts

// Define require function for TypeScript to know that it
// will exist at runtime
declare function require(name:string);
// Require your module
var Something = require('my-component/Something');
// var myComponent = require('my-component');

my-component/Something.ts

// Export something (used a function to test)
export function Something() {
    console.log("Hello");
}

my-component/index.ts

// Definition of require function as mentioned before
declare function require(name:string);
// Passing other modules
var exportedModules = {
    Something: require("my-component/Something")
};
export default exportedModules;

这样做,它将不会出现问题,并且会按照你在Webpack中定义的模块名称进行解析。不幸的是,我无法通过import实现它。

我将解决方案推送到了一个存储库。如果需要,请查看!


明白了!我会用相应的方法编辑答案。 - E. Salazar
抱歉,这是我的错 - 我错误地列出了项目配置。webpack.config.js在项目的根目录下。对此我深表歉意。 - marius
你说得对,我唯一看到的可行方式是使用 require 语法。问题似乎是使用 "import ... from absolutePath" 语法时导入没有被正确解决。谢谢! - marius
我通过配置找到了一种不同的解决方案。 - marius
@JeffreyHammansson 配置基于的方法是什么?我在这里看不到。也许只是漏掉了吗? - Konrad Viltersten
显示剩余2条评论

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