Repository navigation
Expand file tree
/
Copy pathvite.config.mjs
More file actions
154 lines (146 loc) · 5.23 KB
/
Copy pathvite.config.mjs
File metadata and controls
154 lines (146 loc) · 5.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/* global process */
import { defineConfig } from 'vite';
import { babel } from '@rollup/plugin-babel';
import { resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { createRequire } from 'node:module';
import {
version,
resolvePackages,
exposedDependencies,
hiddenDependencies,
} from './rollup.config.mjs';
import { templateTag } from '@embroider/vite';
const require = createRequire(import.meta.url);
const projectRoot = dirname(fileURLToPath(import.meta.url));
const { packageName: getPackageName, PackageCache } = require('@embroider/shared-internals');
export default defineConfig(({ mode }) => {
process.env.EMBER_ENV = mode;
const build = {
rollupOptions: {
preserveEntrySignatures: 'strict',
input: ['index.html'],
output: {
preserveModules: true,
},
treeshake: false,
},
minify: mode === 'production',
};
return {
plugins: [
templateTag(),
...(process.env.VITE_STABLE_DECORATORS === 'typescript' ? [typescriptEmit()] : []),
babel({
babelHelpers: 'bundled',
extensions: ['.js', '.ts', '.gjs', '.gts'],
configFile: resolve(dirname(fileURLToPath(import.meta.url)), './babel.test.config.mjs'),
}),
resolvePackages(
{
...exposedDependencies(),
...hiddenDependencies(),
// @glimmer/component is published separately and gets its own rollup
// build, so it's not part of ember-source's build graph. Point the
// test suite at its source, so tests exercise what's in git instead
// of whatever happens to be sitting in its dist/ directory.
'@glimmer/component': resolve(projectRoot, 'packages/@glimmer/component/src/index.ts'),
},
{ enableLocalDebug: true }
),
viteResolverBug(),
version(),
],
// `@glimmer/component` is published as its own v2 addon and is only built
// (into `dist/`) by `rollup.config.mjs`. Tests run straight off source, so
// point the bare specifier at the TypeScript entrypoint instead.
resolve: {
alias: [
{
find: /^@glimmer\/component$/,
replacement: resolve(projectRoot, 'packages/@glimmer/component/src/index.ts'),
},
],
},
optimizeDeps: { noDiscovery: true, include: ['expect-type', 'qunit'] },
publicDir: 'tests/public',
build,
// the stock esbuild support for typescript is horribly broken. For example,
// it will simply remove your decorators.
esbuild: false,
envPrefix: ['VM_', 'VITE_'],
};
});
// Compiles our sources with TypeScript's own emit (with standard decorators)
// before babel sees them, so we can test Ember against TypeScript's decorator
// implementation rather than babel's.
function typescriptEmit() {
const ts = require('typescript');
return {
name: 'typescript-emit',
// TypeScript's emit only provides decorator metadata if `Symbol.metadata`
// exists, which it doesn't in browsers yet. Ember relies on that metadata,
// so apps using TypeScript's emit must polyfill it, as we do here.
transformIndexHtml() {
return [
{
tag: 'script',
children: `Symbol.metadata ??= Symbol('Symbol.metadata');`,
injectTo: 'head-prepend',
},
];
},
transform(code, id) {
let [file] = id.split('?');
if (file.includes('/node_modules/') || !/\.(js|ts|gjs|gts)$/.test(file)) {
return;
}
let { outputText, sourceMapText } = ts.transpileModule(code, {
// TypeScript doesn't know about .gjs/.gts, which templateTag() has
// already turned into plain JS/TS by now.
fileName: file.replace(/\.gjs$/, '.js').replace(/\.gts$/, '.ts'),
compilerOptions: {
// ES2022 rather than ESNext, since for ESNext TypeScript leaves
// decorators as-is instead of compiling them.
target: ts.ScriptTarget.ES2022,
module: ts.ModuleKind.ESNext,
experimentalDecorators: false,
allowJs: true,
sourceMap: true,
},
});
return {
code: outputText.replace(/^\/\/# sourceMappingURL=.*$/m, ''),
map: sourceMapText,
};
},
};
}
function viteResolverBug() {
const packageCache = new PackageCache(projectRoot);
// https://github.com/vitejs/vite/issues/9731
return {
name: 'vite-resolver-bug',
resolveId(imported, importer) {
let packageName = getPackageName(imported);
if (packageName && importer) {
let owner = packageCache.ownerOfFile(importer);
if (owner?.name === packageName) {
// Our workaround for a vite bug also hits an actual node bug.🤡 You'd
// think we could pass `paths` to require.resolve in order to do the
// self-reference resolution ourselves, but you'd be wrong.
// https://github.com/nodejs/node/issues/47681
//
// So instead we have a very minimalist and incomplete implementation
// that's just good enough for the features we use
let hit = owner.packageJSON.exports?.['.' + imported.slice(packageName.length)];
if (hit) {
return {
id: resolve(owner.root, hit),
};
}
}
}
},
};
}