モチベーション
- 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しか書かないという強い意志が無ければここまでたどり着けなかった。