Skip to content

Commit

Permalink
Merge pull request #1840 from embroider-build/vite-tests
Browse files Browse the repository at this point in the history
Use Vite for all tests
  • Loading branch information
ef4 authored Apr 2, 2024
2 parents bdb7f3d + d91c9fe commit 8e692cc
Show file tree
Hide file tree
Showing 63 changed files with 1,104 additions and 933 deletions.
14 changes: 1 addition & 13 deletions packages/addon-shim/.prettierignore
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
# unconventional js
/blueprints/*/files/
/vendor/

# compiled output
/dist/
/tmp/

# dependencies
/bower_components/
/node_modules/

# misc
/coverage/
!.*
.eslintcache
.lint-todo/
.*/

# ember-try
/.node_modules.ember-try/
/bower.json.ember-try
/npm-shrinkwrap.json.ember-try
/package.json.ember-try
/package-lock.json.ember-try
/yarn.lock.ember-try
4 changes: 2 additions & 2 deletions packages/compat/src/babel-plugin-adjust-imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ImportUtil } from 'babel-import-util';
import { readJSONSync } from 'fs-extra';
import type { CompatResolverOptions } from './resolver-transform';
import type { Package } from '@embroider/core';
import { locateEmbroiderWorkingDir, packageName, Resolver, unrelativize } from '@embroider/core';
import { cleanUrl, locateEmbroiderWorkingDir, packageName, Resolver, unrelativize } from '@embroider/core';
import { snippetToDasherizedName } from './dasherize-component-name';
import type { ActivePackageRules, ComponentRules, ModuleRules, TemplateRules } from './dependency-rules';
import { appTreeRulesDir } from './dependency-rules';
Expand Down Expand Up @@ -73,7 +73,7 @@ export default function main(babel: typeof Babel) {
};

function addExtraImports(t: BabelTypes, path: NodePath<t.Program>, config: InternalConfig) {
let filename: string = (path.hub as any).file.opts.filename;
let filename: string = cleanUrl((path.hub as any).file.opts.filename);
let entry = config.extraImports[filename];
let adder = new ImportUtil(t, path);
if (entry) {
Expand Down
6 changes: 5 additions & 1 deletion packages/compat/src/resolver-transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { join, sep } from 'path';
import { readJSONSync } from 'fs-extra';
import { dasherize, snippetToDasherizedName } from './dasherize-component-name';
import type { ResolverOptions as CoreResolverOptions } from '@embroider/core';
import { Resolver, locateEmbroiderWorkingDir } from '@embroider/core';
import { Resolver, cleanUrl, locateEmbroiderWorkingDir } from '@embroider/core';
import type CompatOptions from './options';
import type { AuditMessage, Loc } from './audit';
import { camelCase, mergeWith } from 'lodash';
Expand Down Expand Up @@ -342,6 +342,10 @@ class TemplateResolver implements ASTPlugin {
}

private findRules(absPath: string): PreprocessedComponentRule | undefined {
// when babel is invoked by vite our filenames can have query params still
// hanging off them. That would break rule matching.
absPath = cleanUrl(absPath, true);

let fileRules = this.rules.files.get(absPath);
let componentRules: PreprocessedComponentRule | undefined;

Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/module-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,9 @@ export class Resolver {
let fastbootFile = engineConfig.fastbootFiles[candidate];
if (fastbootFile) {
if (fastbootFile.shadowedFilename) {
let { names } = describeExports(readFileSync(resolve(pkg.root, fastbootFile.shadowedFilename), 'utf8'), {});
let { names } = describeExports(readFileSync(resolve(pkg.root, fastbootFile.shadowedFilename), 'utf8'), {
configFile: false,
});
let switchFile = fastbootSwitch(candidate, resolve(pkg.root, 'package.json'), names);
if (switchFile === request.fromFile) {
return logTransition('internal lookup from fastbootSwitch', request);
Expand Down Expand Up @@ -1237,7 +1239,7 @@ export class Resolver {
`${matched.entry['app-js'].fromPackageName} declared ${inEngineSpecifier} in packageJSON.ember-addon.app-js, but that module does not exist`
);
}
let { names } = describeExports(readFileSync(foundAppJS.filename, 'utf8'), {});
let { names } = describeExports(readFileSync(foundAppJS.filename, 'utf8'), { configFile: false });
return request.virtualize(fastbootSwitch(matched.matched, resolve(engine.root, 'package.json'), names));
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/test-setup/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"src/index.js"
],
"dependencies": {
"broccoli-plugin": "^4.0.7",
"lodash": "^4.17.21",
"resolve": "^1.20.0"
},
Expand Down
26 changes: 21 additions & 5 deletions packages/test-setup/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { PipelineOptions } from '@embroider/compat';
import type { PackagerConstructor } from '@embroider/core';
import type { Webpack } from '@embroider/webpack';
import Plugin from 'broccoli-plugin';
import { spawn } from 'child_process';

type EmberWebpackOptions = typeof Webpack extends PackagerConstructor<infer Options> ? Options : never;

Expand Down Expand Up @@ -30,10 +32,6 @@ export function maybeEmbroider(app: any, opts: PipelineOptions<EmberWebpackOptio
// - we don't want to load any of these things until they're actually needed;
// - we can't use `await import()` because this function needs to be synchronous to go inside ember-cli-build.js
/* eslint-disable @typescript-eslint/no-require-imports */
let { Webpack } = require(require.resolve('@embroider/webpack', {
paths: [app.project.root],
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
})) as typeof import('@embroider/webpack');
let Compat = require(require.resolve('@embroider/compat', {
paths: [app.project.root],
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
Expand All @@ -52,7 +50,25 @@ export function maybeEmbroider(app: any, opts: PipelineOptions<EmberWebpackOptio
}
}

return Compat.compatBuild(app, Webpack, opts);
if (process.env.EMBROIDER_PREBUILD) {
return Compat.prebuild(app, opts);
}

return new BuildWithVite([]);
}

class BuildWithVite extends Plugin {
build(): Promise<void> {
return new Promise((resolve, reject) => {
const child = spawn(`npx vite build --outDir ${this.outputPath}`, {
cwd: process.cwd(),
shell: true,
stdio: 'inherit',
env: { ...process.env },
});
child.on('exit', code => (code === 0 ? resolve() : reject(new Error('vite build failed'))));
});
}
}

export function embroiderSafe(extension?: object) {
Expand Down
36 changes: 28 additions & 8 deletions packages/vite/src/build.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import { fork } from 'child_process';
import type { Plugin } from 'vite';

export function emberBuild(mode: string): Promise<void> {
if (mode === 'build') {
export function emberBuild(command: string, mode: string): Promise<void> {
if (command === 'build') {
return new Promise((resolve, reject) => {
const child = fork('./node_modules/ember-cli/bin/ember', ['build', '--production']);
const child = fork('./node_modules/ember-cli/bin/ember', ['build', '--environment', mode], {
env: {
...process.env,
EMBROIDER_PREBUILD: 'true',
},
});
child.on('exit', code => (code === 0 ? resolve() : reject()));
});
}
return new Promise((resolve, reject) => {
const child = fork('./node_modules/ember-cli/bin/ember', ['build', '--watch'], { silent: true });
const child = fork('./node_modules/ember-cli/bin/ember', ['build', '--watch', '--environment', mode], {
silent: true,
env: {
...process.env,
EMBROIDER_PREBUILD: 'true',
},
});
child.on('exit', code => (code === 0 ? resolve() : reject(new Error('ember build --watch failed'))));
child.on('spawn', () => {
child.stderr?.on('data', data => {
Expand All @@ -26,15 +37,24 @@ export function emberBuild(mode: string): Promise<void> {
}

export function compatPrebuild(): Plugin {
let mode = 'build';
let viteCommand: string | undefined;
let viteMode: string | undefined;

return {
name: 'embroider-builder',
enforce: 'pre',
configureServer() {
mode = 'development';
config(_config, { mode, command }) {
viteCommand = command;
viteMode = mode;
},
async buildStart() {
await emberBuild(mode);
if (!viteCommand) {
throw new Error(`bug: embroider compatPrebuild did not detect Vite's command`);
}
if (!viteMode) {
throw new Error(`bug: embroider compatPrebuild did not detect Vite's mode`);
}
await emberBuild(viteCommand, viteMode);
},
};
}
5 changes: 2 additions & 3 deletions packages/vite/src/esbuild-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ResolverLoader, virtualContent, locateEmbroiderWorkingDir } from '@embr
import { readFileSync, readJSONSync } from 'fs-extra';
import { EsBuildModuleRequest } from './esbuild-request';
import assertNever from 'assert-never';
import { resolve, join } from 'path';
import { resolve } from 'path';
import { hbsToJS } from '@embroider/core';
import { Preprocessor } from 'content-tag';

Expand Down Expand Up @@ -82,7 +82,6 @@ export function esBuildResolver(root = process.cwd()): EsBuildPlugin {
const code = readFileSync(filename, 'utf8');

const result = transform(preprocessor.process(code, { filename }), {
configFile: join(process.cwd(), 'babel.config.js'),
filename,
});

Expand All @@ -98,7 +97,7 @@ export function esBuildResolver(root = process.cwd()): EsBuildPlugin {
build.onLoad({ filter: /\.hbs$/ }, async ({ path: filename }) => {
const code = readFileSync(filename, 'utf8');

const result = transform(hbsToJS(code), { configFile: join(process.cwd(), 'babel.config.js'), filename });
const result = transform(hbsToJS(code), { filename });

if (!result || !result.code) {
throw new Error(`Failed to load file ${filename} in esbuild-hbs-loader`);
Expand Down
10 changes: 8 additions & 2 deletions packages/vite/src/scripts.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Plugin } from 'vite';
import type { EmittedFile } from 'rollup';
import { JSDOM } from 'jsdom';
import { readFileSync, readJSONSync } from 'fs-extra';
import { readFileSync, readJSONSync, existsSync } from 'fs-extra';
import { dirname, posix, resolve } from 'path';

// This is a type-only import, so it gets compiled away. At runtime, we load
Expand Down Expand Up @@ -65,11 +65,17 @@ class ScriptOptimizer {
constructor(private rootDir: string) {}

async optimizedScript(script: string): Promise<EmittedFile[]> {
let fullName = resolve(this.rootDir, script.slice(1));
if (!existsSync(fullName)) {
// in prod builds, test-support.js isn't going to exist (for example)
return [];
}

// loading these lazily here so they never load in non-production builds.
// The node cache will ensures we only load them once.
const [Terser, srcURL] = await Promise.all([import('terser'), import('source-map-url')]);

let inCode = readFileSync(resolve(this.rootDir, script.slice(1)), 'utf8');
let inCode = readFileSync(fullName, 'utf8');
let terserOpts: MinifyOptions = {};
let fileRelativeSourceMapURL;
let appRelativeSourceMapURL;
Expand Down
Loading

0 comments on commit 8e692cc

Please sign in to comment.