0
Help us understand the problem. What are the problem?

vue-loader + TypeScriptの「Module not found: Error: Can't resolve './listToStyles'」エラー

モチベーション

  • jsだけで構築されたChrome Extensionを作成したい(index.html無しで)
  • *.js は一切書かず、 *.ts *.vue だけ書きたい(webpack.configもTypeScript)

ハマったところ

*.vue ファイルの <style> タグがscssだとコンパイルが通らなかった

a.vue
<style lang='scss'>
ERROR in ./node_modules/vue-style-loader/lib/addStylesClient.js 7:0-41
Module not found: Error: Can't resolve './listToStyles' in 'path/to/webpack-error-reproduction/node_modules/vue-style-loader/lib'

とか

Field 'browser' doesn't contain a valid alias configuration

とかエラーが出て調べたが、何もピンと来るソリューションが見当たらなかった人に、ぜひ良い助けになってほしい。


$ yarn webpack
yarn run v1.22.11
$ path/to/webpack-error-reproduction/node_modules/.bin/webpack
asset index.bundle.js 34.5 KiB [emitted] (name: index)
runtime modules 937 bytes 4 modules
modules by path ./src/ 4.79 KiB
  ./src/index.ts 297 bytes [built] [code generated]
  ./src/a.vue 1.16 KiB [built] [code generated]
  ./src/a.vue?vue&type=template&id=45c6ab58&scoped=true& 205 bytes [built] [code generated]
  ./src/a.vue?vue&type=script&lang=ts& 314 bytes [built] [code generated]
  ./src/a.vue?vue&type=style&index=0&id=45c6ab58&lang=scss&scoped=true& 322 bytes [built] [code generated]
  ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/a.vue?vue&type=template&id=45c6ab58&scoped=true& 212 bytes [built] [code generated]
  ./node_modules/ts-loader/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/a.vue?vue&type=script&lang=ts& 297 bytes [built] [code generated]
  ./node_modules/vue-style-loader/index.js!./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/sass-loader/dist/cjs.js!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/a.vue?vue&type=style&index=0&id=45c6ab58&lang=scss&scoped=true& 1.68 KiB [built] [code generated]
  ./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/sass-loader/dist/cjs.js!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/a.vue?vue&type=style&index=0&id=45c6ab58&lang=scss&scoped=true& 352 bytes [built] [code generated]
modules by path ./node_modules/ 10.4 KiB
  ./node_modules/vue-loader/lib/runtime/componentNormalizer.js 2.71 KiB [built] [code generated]
  ./node_modules/vue-style-loader/lib/addStylesClient.js 6.09 KiB [built] [code generated]
  ./node_modules/css-loader/dist/runtime/api.js 1.57 KiB [built] [code generated]

ERROR in ./node_modules/vue-style-loader/lib/addStylesClient.js 7:0-41
Module not found: Error: Can't resolve './listToStyles' in 'path/to/webpack-error-reproduction/node_modules/vue-style-loader/lib'
resolve './listToStyles' in 'path/to/webpack-error-reproduction/node_modules/vue-style-loader/lib'
  using description file: path/to/webpack-error-reproduction/node_modules/vue-style-loader/package.json (relative path: ./lib)
    Field 'browser' doesn't contain a valid alias configuration
    using description file: path/to/webpack-error-reproduction/node_modules/vue-style-loader/package.json (relative path: ./lib/listToStyles)
      no extension
        Field 'browser' doesn't contain a valid alias configuration
        path/to/webpack-error-reproduction/node_modules/vue-style-loader/lib/listToStyles doesn't exist
      .vue
        Field 'browser' doesn't contain a valid alias configuration
        path/to/webpack-error-reproduction/node_modules/vue-style-loader/lib/listToStyles.vue doesn't exist
      .ts
        Field 'browser' doesn't contain a valid alias configuration
        path/to/webpack-error-reproduction/node_modules/vue-style-loader/lib/listToStyles.ts doesn't exist
      as directory
        path/to/webpack-error-reproduction/node_modules/vue-style-loader/lib/listToStyles doesn't exist
 @ ./node_modules/vue-style-loader/index.js!./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/sass-loader/dist/cjs.js!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/a.vue?vue&type=style&index=0&id=45c6ab58&lang=scss&scoped=true& 9:10-85
 @ ./src/a.vue?vue&type=style&index=0&id=45c6ab58&lang=scss&scoped=true& 1:0-322 1:0-322
 @ ./src/a.vue 4:0-86
 @ ./src/index.ts 6:30-48

webpack 5.53.0 compiled with 1 error in 934 ms
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.


再現状況

ファイル構成はこんな感じ。

▾ src/
    a.vue
    index.ts
    sfc.d.ts
  package.json
  tsconfig.json
  webpack.config.ts
  yarn.lock
package.json
{
  "name": "test",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "css-loader": "^6.2.0",
    "node-sass": "^6.0.1",
    "sass-loader": "^12.1.0",
    "ts-loader": "^9.2.5",
    "ts-node": "^10.2.1",
    "typescript": "^4.4.3",
    "vue-loader": "^15.9.8",
    "vue-template-compiler": "^2.6.14",
    "webpack": "^5.53.0",
    "webpack-cli": "^4.8.0"
  },
  "volta": {
    "node": "14.17.6",
    "yarn": "1.22.11"
  },
  "dependencies": {
    "vue": "^2.6.14"
  }
}

import path from 'path'
import { VueLoaderPlugin }  from 'vue-loader'

export default {
  mode: 'development',

  entry: {
    index: path.join(__dirname, 'src', 'index.ts')
  },

  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].bundle.js'
  },

  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: 'ts-loader',
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader',
      },
      {
        test: /\.pug/,
        loader: 'pug-plain-loader'
      },
      {
        test: /\.scss$/,
        use: ['vue-style-loader', 'css-loader', 'sass-loader']
      }
    ]
  },

  plugins: [
    new VueLoaderPlugin()
  ],

  resolve: {
    extensions: ['.vue', '.ts', '.js'] // .js が無いと「Module not found: Error: Can't resolve './listToStyles'」エラー
  }
}

中身はごくごく単純で、エントリーポイントとなる src/index.ts から src/a.vue を読み込ませ、コンパイル & バンドルした上で dist/index.bundle.js として吐き出すというもの。lintしたり vue-property-decorator を入れたり vuex を入れたりといった余計な設定は極限まで削ぎ落としている。

src/index.ts
import A from './a.vue'
console.log(A)
src/a.vue
<template>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({

})
</script>

<style lang='scss' scoped>
div {
  background-color: #000
}
</style>

修正方法

上記に書いてあるままなのだが、webpackのコンパイルターゲットの拡張子に .js を加えるだけだった。

  resolve: {
-    extensions: ['.vue', '.ts']
+    extensions: ['.vue', '.ts', '.js']
  }

結論に至るまでの試行錯誤集

  • webpack.config .ts が悪さをしているのか?
  • webpack.config.ts の exclude/node_modules/ が無いからいけないのか?
  • entries に設定するファイルの拡張子が .js じゃないとダメなのか?
  • vue-loader の設定が悪いのか?
  • vue-loader のバージョンが悪いのか?
  • ts-loader がダメなのか? vue-loader との相性が悪いのか?
  • ts-loader じゃなくて babel-loader なら良いのか?

記録に残せないほどいろいろ試行錯誤してやっとたどり着けたが、正直なところなんで .js を足せば動くのかよく分からない。
一つ言えるのは絶対にTypeScriptしか書かないという強い意志が無ければここまでたどり着けなかった。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?