Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

app tree resolving #1373

Merged
merged 27 commits into from
Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
28d8317
app tree resolving
ef4 Mar 7, 2023
b58732d
standardize specifiers on windows
ef4 Mar 8, 2023
8b63e28
previous commit on windows didn't run prettier
ef4 Mar 8, 2023
bd668cb
Merge remote-tracking branch 'origin/main' into app-tree-resolving2
ef4 Mar 8, 2023
0813263
switch to shared version of this utility
ef4 Mar 8, 2023
bd58c42
disabling on-disk app-tree merge
ef4 Mar 8, 2023
196f449
simplify searchAppTree
ef4 Mar 8, 2023
fff11ab
implement fastboot switching
ef4 Mar 8, 2023
3c6f162
fix qunit warning
ef4 Mar 9, 2023
f0b8aa4
run virtual-loader-plugin content through babel too
ef4 Mar 9, 2023
4422c09
updating module-resolver rules to account for removal of on-disk app-…
ef4 Mar 9, 2023
f28db6e
update some tests and always resolve symlinks in our nodeResolve
ef4 Mar 9, 2023
36fb27f
update more tests
ef4 Mar 9, 2023
267eee9
fix the ways appTemplates and appModules rules get applied now that t…
ef4 Mar 10, 2023
e958368
update tests to see symlinks
ef4 Mar 10, 2023
73c7fb7
make appTemplates rules apply correctly in apps, not just addons
ef4 Mar 10, 2023
21deccd
update the invokes rules matching too, and update more tests
ef4 Mar 10, 2023
43d0b97
fix rule matching within (moved) app
ef4 Mar 10, 2023
cf738a1
update more tests and add an assertion
ef4 Mar 10, 2023
c7db53f
fix engines config sharing and stop relativizing engine entrypoints
ef4 Mar 10, 2023
7a63175
updating test
ef4 Mar 13, 2023
5dc362e
updating tests
ef4 Mar 13, 2023
838939b
standardized around non-relative implicit-modules
ef4 Mar 13, 2023
ca7f0c6
update more tests
ef4 Mar 13, 2023
c4d7309
remove unused args
ef4 Mar 13, 2023
7a3aa65
updating more tests
ef4 Mar 13, 2023
d885fd0
updating more tests
ef4 Mar 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/compat/src/audit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ export class AuditResults {
}))
: [],
exports: module.linked?.exports ? [...module.linked.exports] : [],
content: module.parsed?.transpiledContent ? module.parsed?.transpiledContent.toString() : '',
content: module.parsed?.transpiledContent
? module.parsed?.transpiledContent.toString()
: 'module failed to transpile',
};
results.modules[explicitRelative(baseDir, filename)] = publicModule;
}
Expand Down
22 changes: 16 additions & 6 deletions packages/compat/src/babel-plugin-adjust-imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { readJSONSync } from 'fs-extra';
import { CompatResolverOptions } from './resolver-transform';
import { Package, packageName, Resolver, unrelativize } from '@embroider/core';
import { snippetToDasherizedName } from './dasherize-component-name';
import { ActivePackageRules, ComponentRules, ModuleRules, TemplateRules } from './dependency-rules';
import { ActivePackageRules, appTreeRulesDir, ComponentRules, ModuleRules, TemplateRules } from './dependency-rules';

export type Options = { appRoot: string };

Expand Down Expand Up @@ -43,10 +43,11 @@ export default function main(babel: typeof Babel) {
return cached;
}
let resolverOptions: CompatResolverOptions = readJSONSync(join(appRoot, '.embroider', 'resolver.json'));
let resolver = new Resolver(resolverOptions);
cached = {
resolverOptions,
resolver: new Resolver(resolverOptions),
extraImports: preprocessExtraImports(resolverOptions),
resolver,
extraImports: preprocessExtraImports(resolverOptions, resolver),
componentExtraImports: preprocessComponentExtraImports(resolverOptions),
};
return cached;
Expand Down Expand Up @@ -133,7 +134,7 @@ function amdDefine(t: BabelTypes, adder: ImportUtil, path: NodePath<t.Program>,
);
}

function preprocessExtraImports(config: CompatResolverOptions): ExtraImports {
function preprocessExtraImports(config: CompatResolverOptions, resolver: Resolver): ExtraImports {
let extraImports: ExtraImports = {};
for (let rule of config.activePackageRules) {
if (rule.addonModules) {
Expand All @@ -145,7 +146,14 @@ function preprocessExtraImports(config: CompatResolverOptions): ExtraImports {
}
if (rule.appModules) {
for (let [filename, moduleRules] of Object.entries(rule.appModules)) {
expandDependsOnRules(config.appRoot, filename, moduleRules, extraImports);
for (let root of rule.roots) {
// in general v2 addons can keep their app tree stuff in other places
// than "_app_" and we would need to check their package.json to see.
// But this code is only for applying packageRules to auto-upgraded v1
// addons, and those we always organize with their treeForApp output
// in _app_.
expandDependsOnRules(appTreeRulesDir(root, resolver), filename, moduleRules, extraImports);
}
}
}
if (rule.addonTemplates) {
Expand All @@ -157,7 +165,9 @@ function preprocessExtraImports(config: CompatResolverOptions): ExtraImports {
}
if (rule.appTemplates) {
for (let [filename, moduleRules] of Object.entries(rule.appTemplates)) {
expandInvokesRules(config.appRoot, filename, moduleRules, extraImports);
for (let root of rule.roots) {
expandInvokesRules(appTreeRulesDir(root, resolver), filename, moduleRules, extraImports);
}
}
}
}
Expand Down
14 changes: 3 additions & 11 deletions packages/compat/src/compat-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ class CompatAppAdapter implements AppAdapter<TreeNames, CompatResolverOptions> {
@Memoize()
private activeRules() {
return activePackageRules(this.options.packageRules.concat(defaultAddonPackageRules()), [
this.appPackage,
{ name: this.appPackage.name, version: this.appPackage.version, root: this.root },
...this.allActiveAddons.filter(p => p.meta['auto-upgraded']),
]);
}
Expand Down Expand Up @@ -354,24 +354,16 @@ class CompatAppAdapter implements AppAdapter<TreeNames, CompatResolverOptions> {
activeAddons[addon.name] = addon.root;
}

let relocatedFiles: CompatResolverOptions['relocatedFiles'] = {};
for (let { destPath, appFiles } of engines) {
for (let [relativePath, originalPath] of appFiles.relocatedFiles) {
relocatedFiles[join(destPath, relativePath)] = originalPath;
}
}

let config: CompatResolverOptions = {
// this part is the base ModuleResolverOptions as required by @embroider/core
activeAddons,
renameModules,
renamePackages,
relocatedFiles,
resolvableExtensions: this.resolvableExtensions(),
appRoot: this.root,
engines: engines.map(engine => ({
engines: engines.map((engine, index) => ({
packageName: engine.package.name,
root: this.root,
root: index === 0 ? this.root : engine.package.root, // first engine is the app, which has been relocated to this.roto
activeAddons: [...engine.addons]
.map(a => ({
name: a.name,
Expand Down
22 changes: 20 additions & 2 deletions packages/compat/src/dependency-rules.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Package, getOrCreate } from '@embroider/core';
import { getOrCreate, Resolver } from '@embroider/core';
import { resolve } from 'path';
import { satisfies } from 'semver';

export interface PackageRules {
Expand Down Expand Up @@ -205,7 +206,10 @@ export function preprocessComponentRule(componentRules: ComponentRules): Preproc
};
}

export function activePackageRules(packageRules: PackageRules[], activePackages: Package[]): ActivePackageRules[] {
export function activePackageRules(
packageRules: PackageRules[],
activePackages: { name: string; root: string; version: string }[]
): ActivePackageRules[] {
// rule order implies precedence. The first rule that matches a given package
// applies to that package, and no other rule does.
let rootsPerRule = new Map();
Expand All @@ -224,3 +228,17 @@ export function activePackageRules(packageRules: PackageRules[], activePackages:
}
return output;
}

export function appTreeRulesDir(root: string, resolver: Resolver) {
let pkg = resolver.owningPackage(root);
if (pkg?.isV2Addon()) {
// in general v2 addons can keep their app tree stuff in other places than
// "_app_" and we would need to check their package.json to see. But this code
// is only for applying packageRules to auto-upgraded v1 addons and apps, and
// those we always organize predictably.
return resolve(root, '_app_');
} else {
// auto-upgraded apps don't get an exist _app_ dir.
return root;
}
}
5 changes: 4 additions & 1 deletion packages/compat/src/resolver-transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ComponentRules,
PackageRules,
ModuleRules,
appTreeRulesDir,
} from './dependency-rules';
import { Memoize } from 'typescript-memoize';
import type { WithJSUtils } from 'babel-plugin-ember-template-compilation';
Expand Down Expand Up @@ -323,7 +324,9 @@ class TemplateResolver implements ASTPlugin {
if (rule.appTemplates) {
for (let [path, templateRules] of Object.entries(rule.appTemplates)) {
let processedRules = preprocessComponentRule(templateRules);
files.set(join(this.config.appRoot, path), processedRules);
for (let root of rule.roots) {
files.set(join(appTreeRulesDir(root, this.moduleResolver), path), processedRules);
}
}
}
if (rule.addonTemplates) {
Expand Down
1 change: 0 additions & 1 deletion packages/compat/tests/audit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ describe('audit', function () {
root: app.baseDir,
},
],
relocatedFiles: {},
resolvableExtensions,
};

Expand Down
48 changes: 24 additions & 24 deletions packages/core/src/app-differ.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,8 @@ export default class AppDiffer {
private sources: Source[];
private firstFastbootTree = Infinity;

// maps from each filename in the app to the original directory from whence it
// came, if it came from an addon. The mapping allows us to preserve
// resolution semantics so that each of the app files can still resolve
// relative to where it was authored.
//
// files authored within the app map to null
readonly files: Map<string, string | null> = new Map();
// set of filenames logically located in the app
readonly files: Set<string> = new Set();

// true for files that are fastboot-only.
isFastbootOnly: Map<string, boolean> = new Map();
Expand Down Expand Up @@ -107,8 +102,10 @@ export default class AppDiffer {
this.isFastbootOnly.set(relativePath, sourceIndices[0] >= this.firstFastbootTree);
let source = this.sources[sourceIndices[0]];
let sourceFile = source.locate(relativePath);
copySync(sourceFile, outputPath, { dereference: true });
this.updateFiles(relativePath, source, sourceFile);
if (!source.isRelocated) {
copySync(sourceFile, outputPath, { dereference: true });
}
this.updateFiles(relativePath);
} else {
// we have both fastboot and non-fastboot files for this path.
// Because of the way fastbootMerge is written, the first one is the
Expand All @@ -122,13 +119,15 @@ export default class AppDiffer {
let base = basename(relativePath);
let browserDest = `_browser_${base}`;
let fastbootDest = `_fastboot_${base}`;
copySync(browserSourceFile, join(this.outputPath, dir, browserDest), { dereference: true });
copySync(fastbootSourceFile, join(this.outputPath, dir, fastbootDest), { dereference: true });
writeFileSync(
outputPath,
switcher(browserDest, fastbootDest, this.babelParserConfig!, readFileSync(browserSourceFile, 'utf8'))
);
this.updateFiles(relativePath, browserSrc, browserSourceFile);
if (!browserSrc.isRelocated && !fastbootSrc.isRelocated) {
copySync(browserSourceFile, join(this.outputPath, dir, browserDest), { dereference: true });
copySync(fastbootSourceFile, join(this.outputPath, dir, fastbootDest), { dereference: true });
writeFileSync(
outputPath,
switcher(browserDest, fastbootDest, this.babelParserConfig!, readFileSync(browserSourceFile, 'utf8'))
);
}
this.updateFiles(relativePath);
}
break;
default:
Expand All @@ -137,12 +136,8 @@ export default class AppDiffer {
}
}

private updateFiles(relativePath: string, source: Source, sourceFile: string) {
if (source.isRelocated) {
this.files.set(relativePath, sourceFile);
} else {
this.files.set(relativePath, null);
}
private updateFiles(relativePath: string) {
this.files.add(relativePath);
}
}

Expand Down Expand Up @@ -194,8 +189,13 @@ function switcher(
babelParserConfig: TransformOptions,
browserSource: string
): string {
let { names, hasDefaultExport } = describeExports(browserSource, babelParserConfig);
return switcherTemplate({ fastbootDest, browserDest, names: [...names], hasDefaultExport });
let { names } = describeExports(browserSource, babelParserConfig);
return switcherTemplate({
fastbootDest,
browserDest,
names: [...names].filter(name => name !== 'default'),
hasDefaultExport: names.has('default'),
});
}

interface Source extends InputTree {
Expand Down
9 changes: 0 additions & 9 deletions packages/core/src/app-files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export class AppFiles {
readonly modifiers: ReadonlyArray<string>;
private perRoute: RouteFiles;
readonly otherAppFiles: ReadonlyArray<string>;
readonly relocatedFiles: Map<string, string>;
readonly isFastbootOnly: Map<string, boolean>;

constructor(appDiffer: AppDiffer, resolvableExtensions: RegExp, podModulePrefix?: string) {
Expand Down Expand Up @@ -83,14 +82,6 @@ export class AppFiles {
this.helpers = helpers;
this.modifiers = modifiers;
this.otherAppFiles = otherAppFiles;

let relocatedFiles: Map<string, string> = new Map();
for (let [relativePath, owningPath] of appDiffer.files) {
if (owningPath) {
relocatedFiles.set(relativePath, owningPath);
}
}
this.relocatedFiles = relocatedFiles;
this.isFastbootOnly = appDiffer.isFastbootOnly;
}

Expand Down
29 changes: 12 additions & 17 deletions packages/core/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { compile } from './js-handlebars';
import resolve from 'resolve';
import { Memoize } from 'typescript-memoize';
import { copySync, ensureDirSync, outputJSONSync, readJSONSync, statSync, unlinkSync, writeFileSync } from 'fs-extra';
import { dirname, join, resolve as resolvePath, sep } from 'path';
import { dirname, join, resolve as resolvePath, sep, posix } from 'path';
import { debug, warn } from './messages';
import sortBy from 'lodash/sortBy';
import flatten from 'lodash/flatten';
Expand Down Expand Up @@ -1183,7 +1183,7 @@ export class AppBuilder<TreeNames> {
}
lazyRoutes.push({
names: routeNames,
path: this.importPaths(engine, routeEntrypoint, relativePath).buildtime,
path: this.importPaths(engine, routeEntrypoint).buildtime,
});
}
);
Expand All @@ -1192,12 +1192,12 @@ export class AppBuilder<TreeNames> {
let [fastboot, nonFastboot] = partition(excludeDotFiles(flatten(requiredAppFiles)), file =>
appFiles.isFastbootOnly.get(file)
);
let amdModules = nonFastboot.map(file => this.importPaths(engine, file, relativePath));
let fastbootOnlyAmdModules = fastboot.map(file => this.importPaths(engine, file, relativePath));
let amdModules = nonFastboot.map(file => this.importPaths(engine, file));
let fastbootOnlyAmdModules = fastboot.map(file => this.importPaths(engine, file));

// this is a backward-compatibility feature: addons can force inclusion of
// modules.
this.gatherImplicitModules('implicit-modules', relativePath, engine, amdModules);
this.gatherImplicitModules('implicit-modules', engine, amdModules);

let params = { amdModules, fastbootOnlyAmdModules, lazyRoutes, lazyEngines, eagerModules, styles };
if (entryParams) {
Expand All @@ -1220,12 +1220,11 @@ export class AppBuilder<TreeNames> {
return this.adapter.modulePrefix();
}

private importPaths(engine: Engine, engineRelativePath: string, fromFile: string) {
let appRelativePath = join(engine.appRelativePath, engineRelativePath);
private importPaths(engine: Engine, engineRelativePath: string) {
let noHBS = engineRelativePath.replace(this.resolvableExtensionsPattern, '').replace(/\.hbs$/, '');
return {
runtime: `${engine.modulePrefix}/${noHBS}`,
buildtime: explicitRelative(dirname(fromFile), appRelativePath),
buildtime: posix.join(engine.package.name, engineRelativePath),
};
}

Expand All @@ -1235,8 +1234,8 @@ export class AppBuilder<TreeNames> {
let asset: InternalAsset = {
kind: 'in-memory',
source: routeEntryTemplate({
files: nonFastboot.map(f => this.importPaths(engine, f, relativePath)),
fastbootOnlyFiles: fastboot.map(f => this.importPaths(engine, f, relativePath)),
files: nonFastboot.map(f => this.importPaths(engine, f)),
fastbootOnlyFiles: fastboot.map(f => this.importPaths(engine, f)),
}),
relativePath,
};
Expand Down Expand Up @@ -1268,11 +1267,11 @@ export class AppBuilder<TreeNames> {
let amdModules: { runtime: string; buildtime: string }[] = [];
// this is a backward-compatibility feature: addons can force inclusion of
// test support modules.
this.gatherImplicitModules('implicit-test-modules', myName, engine, amdModules);
this.gatherImplicitModules('implicit-test-modules', engine, amdModules);

let { appFiles } = engine;
for (let relativePath of appFiles.tests) {
amdModules.push(this.importPaths(engine, relativePath, myName));
amdModules.push(this.importPaths(engine, relativePath));
}

let source = entryTemplate({
Expand All @@ -1292,7 +1291,6 @@ export class AppBuilder<TreeNames> {

private gatherImplicitModules(
section: 'implicit-modules' | 'implicit-test-modules',
relativeTo: string,
engine: Engine,
lazyModules: { runtime: string; buildtime: string }[]
) {
Expand Down Expand Up @@ -1322,10 +1320,7 @@ export class AppBuilder<TreeNames> {
runtime = runtime.split(sep).join('/');
lazyModules.push({
runtime,
buildtime:
this.options.implicitModulesStrategy === 'packageNames'
? join(packageName, name)
: explicitRelative(dirname(join(this.root, relativeTo)), join(addon.root, name)),
buildtime: posix.join(packageName, name),
});
}
}
Expand Down
Loading