typescript - pnpm & vue & vite monorepo - riješiti uvoz alias puta unutar paketa radnog prostora
Gradim monorepo UI aplikacija koristeći zajedničke komponente i stilove koristeći pnpm, TypeScript, Vue i Vite.
Dok pokušavam iskoristiti pnpm-ov ekosustav radnog prostora kako bih olakšao iskustvo razvoja i implementacije, mučim se s korištenjem alias putanja pri uvozu paketa u aplikaciju.
Ovo je struktura mojih mapa:
src/
|
|- apps/
| |- app1/
| | |- env/
| | |- node_modules/
| | |- src/
| | | |- plugins/
| | | | |- some-logic.ts
| | | |- styles/
| | | | |- app.scss
| | | |- views/
| | | | |- HomeView.vue
| | | ...
| | | |- App.vue
| | | |- main.ts
| | |
| | |- index.html
| | |- package.json
| | |- tsconfig.json
| | |- vite.config.ts
|
|- packages/
| |- shared-ui/
| | |- node_modules/
| | |- src/
| | | |- components/
| | | | |- Header.vue
| | | |- plugins/
| | | | |- another-logic.ts
| | | |- styles/
| | | | |- header.scss
| | |- package.json
| | |- tsconfig.json
|
|- node_modules/
...
|- package.json
|- pnpm-lock.yaml
|- pnpm-workspace.yaml
|- tsconfig.base.json
...
|- package.json
|- pnpm-lock.yaml
|- pnpm-workspace.yaml
|- tsconfig.base.json
Moj HomeView.vue u mojoj aplikaciji uvozi Header.vue komponentu iz mog shared-ui paketa:
<script setup lang="ts">
import stuff from '@/plugins/some-logic.ts'
import Header from '@namespace/shared-ui/src/components/Header.vue';
stuff();
</script>
<template>
<div class="container">
<Header />
</div>
</template>
<style lang="scss">
@import '@/styles/app.scss';
</style>
Kao što možete vidjeti gore, @/ djeluje kao alias puta za src mapu aplikacije. Ovo radi kako se očekuje. Problem počinje u okviru Header komponente:
<script setup lang="ts">
import moreStuff from '@/plugins/another-logic.ts' // doesn't work
moreStuff();
</script>
<template>
<div class="header">
...
</div>
</template>
<style lang="scss">
// @import '@/styles/header.scss'; // doesn't work
@import '../styles/header.scss'; // works
</style>
Moje je mišljenje da budući da je ulazna točka vite src/apps/app1/, a u vite konfiguraciji sam napravio alias @ za src/, pokušava riješiti @ paketa također, što dovodi do pogrešnog uvoza kao što je opisano u nastavku:
import/no-unresolved Unable to resolve path to module '@/plugins/another-logic.ts'
import/no-unresolved [vite] Internal server error: [sass] ENOENT: no such file or directory, open '/namespace/apps/app1/src/styles/header.scss'
root package.json
{
"name": "namespace",
"private": true,
"type": "module",
"packageManager": "[email ",
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie <= 11"
],
"devDependencies": {
"@types/node": "~20.3.3",
"@typescript-eslint/eslint-plugin": "~5.61.0",
"@typescript-eslint/parser": "~5.61.0",
"eslint": "~8.44.0",
"eslint-config-prettier": "~8.8.0",
"eslint-import-resolver-typescript": "~3.5.5",
"eslint-plugin-import": "~2.27.5",
"eslint-plugin-prettier": "~4.2.1",
"eslint-plugin-vue": "~9.15.1",
"prettier": "~2.8.8",
"ts-node": "~10.9.1",
"typescript": "~5.1.6",
"vite": "~4.3.9",
"vite-plugin-eslint": "~1.8.1",
"vue-eslint-parser": "~9.3.1"
}
}
pnpm-radni-prostor.yaml
packages:
- 'apps/*'
- 'packages/*'
tsconfig.base.json
{
"compilerOptions": {
"target": "es6",
"module": "esnext",
"moduleResolution": "node",
"esModuleInterop": true,
"isolatedModules": true,
"strict": true,
"jsx": "preserve",
"experimentalDecorators": true,
"noEmit": false,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"useDefineForClassFields": true,
"sourceMap": true,
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"references": [
{
"path": "./packages/shared-ui"
}
],
"exclude": [
"**/node_modules",
"packages/**/dist"
]
}
apps/app1/package.json
{
"name": "@namespace/app1",
"private": true,
"type": "module",
"packageManager": "[email ",
"scripts": {
"serve": "vite"
},
"dependencies": {
"@namespace/shared-ui": "workspace:*",
"@vee-validate/zod": "~4.10.8",
"axios": "~1.4.0",
"pinia": "~2.1.4",
"vee-validate": "~4.10.8",
"vite-plugin-vuetify": "~1.0.2",
"vue": "~3.3.4",
"vue-router": "~4.2.4",
"vuetify": "~3.3.6",
"zod": "~3.21.4"
},
"devDependencies": {
"@vitejs/plugin-vue": "~4.2.3",
"sass": "~1.64.1",
"vite-tsconfig-paths": "~4.2.0"
}
}
apps/app1/tsconfig.json
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/",
"paths": {
"@/*": [
"src/*"
]
},
"typeRoots": [
"./node_modules/@types",
"./src/types"
]
},
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"vite.config.ts"
]
}
apps/app1/vite.config.ts
import { type UserConfigExport, defineConfig } from 'vite';
import eslint from 'vite-plugin-eslint';
import vuetify from 'vite-plugin-vuetify';
import tsconfigPaths from 'vite-tsconfig-paths';
import vue from '@vitejs/plugin-vue';
export default defineConfig(({ mode }) => {
const isDevelopment = mode === 'development';
const config: UserConfigExport = {
root: `${process.cwd()}/`,
envDir: `${process.cwd()}/env/`,
plugins: [tsconfigPaths(), eslint(), vue(), vuetify()],
resolve: {
alias: {
'@/': `${process.cwd()}/src/`,
vue: 'vue/dist/vue.esm-bundler.js'
}
}
};
if (isDevelopment) {
config.server = {
host: true,
port: Number(process.env.PORT)
};
}
return config;
});
paketi/shared-ui/package.json
{
"name": "@namespace/shared-ui",
"private": true,
"type": "module",
"packageManager": "[email ",
"dependencies": {
"axios": "~1.4.0"
},
"devDependencies": {
"@vee-validate/zod": "~4.10.8",
"vee-validate": "~4.10.8",
"vue": "~3.3.4",
"vuetify": "~3.3.6",
"zod": "~3.21.4"
}
}
packages/shared-ui/tsconfig.json
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/",
"paths": {
"@/*": [
"src/*"
]
},
"typeRoots": [
"./node_modules/@types",
"./src/types"
]
},
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue"
]
}
Odgovor #1
Kao što je opisano na sljedećem URL-u, vite (i rollup) očito ne podržavaju rješavanje aliasa s nizom već samo s nizom znakova. Rješenje, u ovom trenutku, je odabrati različite alijase po aplikaciji/paketu.
https://github.com/vercel/turbo/discussions/620#discussioncomment-2136195
Odgovor #2
moj slučaj s nextJS gdje
```
pnpm-workspace.yaml
packages:
- app
- packages/*
```
Zamijenio sam:
"@/*": ["src/*"] -> "@<package_name>/*": ["src/*"]
and in /app/tsconfig.json added:
"@<package_name>/*": ["../packages/<package_name>/src/*"]
Trebao bi se prevesti u vue & vite monorepo.
