【问题标题】:Webpack searching in wrong subdirectory with relative importWebpack 使用相对导入在错误的子目录中搜索
【发布时间】:2021-05-28 18:15:40
【问题描述】:

我有一个 Vue (v3 w/ TS) 应用程序嵌套在一个目录中(/my-vue-app),在包含它的目录中,我的 Node.js 服务器代码(不是 TS)还有另一个文件夹,其中我正在使用 SSR Vue 应用程序。这是我的目录结构:

- /app-container
    |
    - /app-container/.babelrc.json
    - /app-container/webpack.server.js
    - /app-container/my-vue-app
       |
       - /app-container/my-vue-app/babel.config.js
       - /app-container/my-vue-app/package.json
       - /app-container/my-vue-app/tsconfig.json
       - /app-container/my-vue-app/public
       - /app-container/my-vue-app/src
          |
          - /app-container/my-vue-app/src/App.ts
          - /app-container/my-vue-app/src/main.ts
          - /app-container/my-vue-app/src/views
             | -- some stuff
          - /app-container/my-vue-app/src/components
             | -- some stuff
          - /app-container/my-vue-app/src/router
             |
             - /app-container/my-vue-app/src/router/index.ts
    - /app-container/server
        |
        - /app-container/server/index.js

这一切看起来都相当标准,我可以使用import App from '../vue-platform-app/src/App';server/index.js 导入/app-container/my-vue-app/src/App.ts,正如预期的那样。

但是,当我尝试从 main.ts 导入 App.ts 时,我收到一个非常奇怪的错误,即“未找到该模块”。我尝试了以下导入语法:

// This does not
import App from "./App";
// Throws error complaining about .ts extension
import App from "App.ts";
// As per `vue create`, @ is configured to /src
import App from "@/App"
// Understandably, this is not found - but it was worth a try
import App from "/my-vue-app/src/App"

// This worked
import App from "C:\\absolute\\path\\to\\app-container\\my-vue-app\\src\\App";

对于第一个,"./App"(这是我、我的 IDE 和 Typescript 都希望工作的那个),我发现 Webpack 似乎在错误的目录中搜索 - 出于某种原因,它正在寻找在/my-vue-app/src/views 而不仅仅是/src,因此,它没有找到它。与--stats verbose

Module not found: Error: Can't resolve './App' in 'C:\absolute\path\to\app-container\my-vue-app\src\views'
resolve './App' in 'C:\absolute\path\to\app-container\my-vue-app\src\views'
  using description file: C:\absolute\path\to\app-container\my-vue-app\package.json (relative path: ./src/views)
    using description file: C:\absolute\path\to\app-container\my-vue-app\package.json (relative path: ./src/views/App)
      no extension
        C:\absolute\path\to\app-container\my-vue-app\src\views\App doesn't exist
      .tsx
        C:\absolute\path\to\app-container\my-vue-app\src\views\App.tsx doesn't exist
      .ts
        C:\absolute\path\to\app-container\my-vue-app\src\views\App.ts doesn't exist
      .js
        C:\absolute\path\to\app-container\my-vue-app\views\App.js doesn't exist
      .jsx
        C:\absolute\path\to\app-container\my-vue-app\src\views\App.jsx doesn't exist
      .css
        C:\absolute\path\to\app-container\my-vue-app\src\views\App.css doesn't exist
      .scss
        C:\absolute\path\to\app-container\my-vue-app\src\views\App.scss doesn't exist
      .sass
        C:\absolute\path\to\app-container\my-vue-app\src\views\App.sass doesn't exist
      .vue
        C:\absolute\path\to\app-container\my-vue-app\src\views\App.vue doesn't exist
      as directory
        C:\absolute\path\to\app-container\my-vue-app\src\views\App doesn't exist

...
webpack:///./vue-platform-app/src/views/Home.vue?./node_modules/ts-loader!./node_modules/vue-loader/dist??ref--13-0:4
!(function webpackMissingModule() { var e = new Error("Cannot find module './App'"); e.code = 'MODULE_NOT_FOUND'; throw e; }());
                                                                                                                  ^

Error: Cannot find module './App'
    at webpackMissingModule (webpack:///./my-vue-app/src/views/Home.vue?./node_modules/ts-loader!./node_modules/vue-loader/dist??ref--13-0:4:45)
    at eval (webpack:///./my-vue-app/src/views/Home.vue?./node_modules/ts-loader!./node_modules/vue-loader/dist??ref--13-0:4:125)

此错误仅在我从 Node 应用程序导入 App.ts 时发生。如果我只是在/my-vue-app 中执行yarn run serve,它会完美编译。

此外,使用@/App,它会尝试在项目根目录中的/my-vue-app/node_modules/node_modules 中将其作为模块进行搜索。

供参考,这是我的webpack.server.js

module.exports = {
    entry: './server/index.js',
    target: 'node',

    externals: [nodeExternals()],

    output: {
        path: path.resolve('server-build'),
        filename: 'index.js',
    },

    resolve: {
        extensions: ['.tsx', '.ts', '.js', '.jsx', '.css', '.scss', '.sass', '.vue']
    },

    plugins: [new VueLoaderPlugin(), ...],

    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader',
            },
            {
                test: /\.jsx?$/,
                loader: 'babel-loader',
                exclude: /node_modules/,
                options: {
                    'presets': [
                        '@babel/preset-env',
                        '@babel/preset-react',
                    ],
                    'plugins': [
                        '@babel/plugin-transform-react-jsx',
                        '@babel/plugin-proposal-class-properties',
                    ],
                },
            },
            ...
        ],
    },
};

这是我在项目根目录中的.babelrc.json

{
    "presets": [
        "@babel/preset-env"
    ],
    "plugins": [
        "@babel/plugin-transform-react-jsx"
    ]
}

这里是babel.config.js in /my-vue-app

module.exports = {
  extends: '../.babelrc',
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}

tsconfig.json 在项目根目录中:

{
    "compilerOptions": {
        "outDir": "./dist/",
        "noImplicitAny": true,
        "module": "esnext",
        "allowSyntheticDefaultImports": true,
        "importHelpers": true,
        "moduleResolution": "node",
        "target": "es5",
        "jsx": "react",
        "allowJs": true,
        "baseUrl": ".",
        "paths": {
            "@/*": [
                "vue-platform-app/src/*"
            ]
        },
        "types": [
            "webpack-env"
        ],
        "lib": [
            "esnext",
            "dom",
            "dom.iterable",
            "scripthost"
        ]
    }
}

tsconfig.json in /my-vue-app(由vue create生成):

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ],
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

这些模块的以下版本安装在/package.json/my-vue-app/package.json 中(为了更好的衡量标准):

"@typescript-eslint/eslint-plugin": "^2.33.0",
"@typescript-eslint/parser": "^2.33.0",
"@vue/cli-plugin-babel": "^4.5.11",
"@vue/cli-plugin-eslint": "^5.0.0-alpha.5",
"@vue/cli-plugin-pwa": "^5.0.0-alpha.5",
"@vue/cli-plugin-router": "^5.0.0-alpha.5",
"@vue/cli-plugin-typescript": "^5.0.0-alpha.5",
"@vue/cli-service": "~4.5.0",
"@vue/eslint-config-typescript": "3"
"typescript": "~3.9.3"
"vue": "^3.0.6",

webpack-cli@^4.5.0 安装在项目根目录中。

我能想到的唯一两个解决方案是包含文件的绝对路径(这非常混乱),或者在import App from "App.ts"; 上方使用// @ts-ignore(这会导致许多其他错误/意味着不TS 类型检查)。

我该怎么做才能正常导入?我几乎可以肯定在我的一个配置文件中搞砸了一些东西 - 我该如何解决这个问题?

【问题讨论】:

  • 从错误消息看来,当 Webpack 处理 src/views/Home.vue 时抛出错误,而不是你建议的 main.ts...
  • 另外,如果您使用@ 别名,则需要在两个环境中都定义它。对于客户端包,它由 Vue CLI webpack 配置定义。对于服务器捆绑包 (webpack.server.js),您需要自己定义它...
  • @MichalLevý 肯定 "@/*": ["vue-platform-app/src/*"] 在顶级 tsconfig.json 会这样做吗?
  • 我不这么认为。那是 TS 配置,不是 Webpack...
  • @MichalLevý 同样关于它在Home.vue - 这是真的;我没有注意到——但它看起来很奇怪。除了默认的import HelloWorld from 'src/components/HelloWorld.vue';(在vue start 的示例项目中)之外,Home.vue 中没有导入。即使在删除该导入/对组件的引用之后,仍然存在相同的错误。

标签: typescript vue.js webpack import vuejs3


【解决方案1】:

如果你在 Vue 代码中使用 @ 别名,则需要在两个环境中都定义它。对于客户端包,它由 Vue CLI webpack 配置定义。对于服务器捆绑包,您需要自己定义它...

webpack.server.js

const path = require('path')

module.exports = {

  resolve: {
    alias: {
      '@': path.resolve(__dirname, './vue-platform-app/src')
    },
    extensions: ['.tsx', '.ts', '.js', '.jsx', '.css', '.scss', '.sass', '.vue']
  },
}

【讨论】:

  • ./vue-platform-app/src 解析为C:\Users\...\vue-platform-app\src\views\vue-platform-app\src,而/vue-platform-app/src 仅解析为/vue-platform-app/src(没有C: 导致它)并声称它找不到模块。
  • 绝对奇怪。您可以尝试更新的代码吗? ....这将使其成为绝对路径
猜你喜欢
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
  • 1970-01-01
  • 2019-04-14
  • 1970-01-01
  • 1970-01-01
  • 2018-06-06
相关资源
最近更新 更多