From 68a783777199030a499939a61f55a75debb198d9 Mon Sep 17 00:00:00 2001 From: Matthew Edwards Date: Thu, 19 May 2022 11:51:41 -0700 Subject: [PATCH 1/6] Wrap preprocesor tree with moduleName before transform --- packages/compat/package.json | 5 +- packages/compat/src/v1-addon.ts | 8 ++ packages/compat/tests/preprocessors.test.ts | 125 ++++++++++++++++++++ 3 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 packages/compat/tests/preprocessors.test.ts diff --git a/packages/compat/package.json b/packages/compat/package.json index d44fd3bc8..98c25ae34 100644 --- a/packages/compat/package.json +++ b/packages/compat/package.json @@ -64,6 +64,7 @@ "devDependencies": { "@embroider/sample-transforms": "0.0.0", "@embroider/test-support": "0.36.0", + "@glimmer/syntax": "0.80.0", "@types/babel__core": "^7.1.14", "@types/babel__generator": "^7.6.2", "@types/babel__template": "^7.4.0", @@ -77,9 +78,9 @@ "@types/resolve": "^1.20.0", "@types/semver": "^7.3.6", "@types/strip-bom": "^4.0.1", - "ember-cli-htmlbars-inline-precompile": "^2.1.0", + "broccoli-stew": "^3.0.0", "ember-cli-htmlbars-3": "npm:ember-cli-htmlbars@3", - "@glimmer/syntax": "0.80.0", + "ember-cli-htmlbars-inline-precompile": "^2.1.0", "ember-engines": "^0.8.19", "typescript": "*" }, diff --git a/packages/compat/src/v1-addon.ts b/packages/compat/src/v1-addon.ts index c7b69ef9d..b464a706c 100644 --- a/packages/compat/src/v1-addon.ts +++ b/packages/compat/src/v1-addon.ts @@ -488,14 +488,22 @@ export default class V1Addon { // applies preprocessors to JS and HBS private transpile(tree: Node) { + tree = buildFunnel(tree, { destDir: this.moduleName }); + tree = this.addonInstance.preprocessJs(tree, '/', this.moduleName, { registry: this.addonInstance.registry, }); + if (this.addonInstance.shouldCompileTemplates() && this.addonInstance.registry.load('template')?.length > 0) { tree = this.app.preprocessRegistry.preprocessTemplates(tree, { registry: this.addonInstance.registry, }); } + + tree = buildFunnel(tree, { + srcDir: this.moduleName, + }); + return tree; } diff --git a/packages/compat/tests/preprocessors.test.ts b/packages/compat/tests/preprocessors.test.ts new file mode 100644 index 000000000..9e07694c5 --- /dev/null +++ b/packages/compat/tests/preprocessors.test.ts @@ -0,0 +1,125 @@ +import { Project, BuildResult, expectFilesAt, ExpectFile } from '@embroider/test-support'; +import { throwOnWarnings } from '@embroider/core'; +import merge from 'lodash/merge'; + +describe('preprocessors tests', function () { + jest.setTimeout(120000); + let build: BuildResult; + let app: Project; + let expectFile: ExpectFile; + + throwOnWarnings(); + + beforeAll(async function () { + app = Project.emberNew('my-app'); + + const PACKAGE_MY_PREPROCESSOR = 'my-preprocessor'; + + merge(app.files, { + config: { + 'targets.js': `module.exports = { browsers: ['last 1 Chrome versions'] }`, + }, + app: { + components: { + 'from-the-app.js': ` + import Component from '@glimmer/component'; + export default class extends Component {} + `, + 'from-the-app.hbs': `
{{this.title}}
`, + }, + }, + }); + + let addonPreprocessor = app.addAddon(PACKAGE_MY_PREPROCESSOR); + + const INDEX_JS_WITH_PREPROCESSOR = `const { map } = require('broccoli-stew'); + +module.exports = { + name: require('./package').name, + + setupPreprocessorRegistry(type, registry) { + if (type !== 'parent') { + return; + } + + registry.add('js', { + name: 'special-path-processor', + toTree(tree, inputPath) { + if (inputPath !== '/') { + return tree; + } + + let augmented = map( + tree, + '**/*.{js,css}', + function (content, relativePath) { + console.log('$$$$' + relativePath); + return \`/*path@\${relativePath}*/\n\${content}\`; + } + ); + return augmented; + }, + }); + } +}; +`; + + addonPreprocessor.linkDevPackage('broccoli-stew'); + addonPreprocessor.files['index.js'] = INDEX_JS_WITH_PREPROCESSOR; + + let addon = app.addAddon('my-addon'); + + merge(addon.files, { + app: { + components: { + 'greeting.js': `export { default } from 'my-addon/components/greeting';`, + }, + }, + addon: { + components: { + 'greeting.js': ` + import Component from '@glimmer/component'; + export default class extends Component {} + `, + 'greeting.hbs': `Hello World`, + }, + }, + }); + + addon.addDependency(PACKAGE_MY_PREPROCESSOR); + + build = await BuildResult.build(app, { + stage: 2, + type: 'app', + emberAppOptions: { + tests: false, + }, + }); + expectFile = expectFilesAt(build.outputPath); + }); + + afterAll(async () => { + await build.cleanup(); + }); + + test('dependencies are setup for this test suite correctly', () => { + expectFile('package.json').exists(); + expectFile('package.json').matches(/my-preprocessor/, 'has the preprocessor dependency'); + expectFile('node_modules/my-addon/package.json').exists(); + expectFile('node_modules/my-addon/package.json').matches(/my-preprocessor/, 'has the preprocessor dependency'); + expectFile('node_modules/my-preprocessor/package.json').exists(); + }); + + test.skip('app has correct path embedded in comment', () => { + const assertFile = expectFile('components/from-the-app.js'); + assertFile.exists(); + // This is the expected output during an classic build. + assertFile.matches(/path:my-app\/components\/from-the-app\.js/, 'has a path comment in app components'); + }); + + test('addon has correct path embedded in comment', () => { + expectFile('node_modules/my-preprocessor/package.json').exists(); + const assertFile = expectFile('node_modules/my-addon/components/greeting.js'); + assertFile.matches(/\/\/path:my-addon\/components\/from-the-app\.js/, 'has a path comment in app components'); + }); +}); From 424a901189c6f46cf77e3b4e45703dfb1f559cbf Mon Sep 17 00:00:00 2001 From: Matthew Edwards Date: Thu, 19 May 2022 12:06:05 -0700 Subject: [PATCH 2/6] Scope app with name when passed to preprocessors --- packages/compat/src/v1-app.ts | 8 +++++++- packages/compat/tests/preprocessors.test.ts | 8 ++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/compat/src/v1-app.ts b/packages/compat/src/v1-app.ts index 1d12d2396..ac06e7fbf 100644 --- a/packages/compat/src/v1-app.ts +++ b/packages/compat/src/v1-app.ts @@ -551,10 +551,16 @@ export default class V1App { // auto-import is supported natively so we don't need it here this.app.registry.remove('js', 'ember-auto-import-analyzer'); - return this.preprocessors.preprocessJs(tree, `/`, '/', { + tree = buildFunnel(tree, { destDir: this.name }); + + tree = this.preprocessors.preprocessJs(tree, `/`, '/', { annotation: 'v1-app-preprocess-js', registry: this.app.registry, }); + + tree = buildFunnel(tree, { srcDir: this.name }); + + return tree; } get htmlbarsPlugins(): TemplateCompilerPlugins { diff --git a/packages/compat/tests/preprocessors.test.ts b/packages/compat/tests/preprocessors.test.ts index 9e07694c5..c9a4bde17 100644 --- a/packages/compat/tests/preprocessors.test.ts +++ b/packages/compat/tests/preprocessors.test.ts @@ -53,7 +53,6 @@ module.exports = { tree, '**/*.{js,css}', function (content, relativePath) { - console.log('$$$$' + relativePath); return \`/*path@\${relativePath}*/\n\${content}\`; } ); @@ -95,6 +94,7 @@ module.exports = { tests: false, }, }); + console.log(build.outputPath); expectFile = expectFilesAt(build.outputPath); }); @@ -110,16 +110,16 @@ module.exports = { expectFile('node_modules/my-preprocessor/package.json').exists(); }); - test.skip('app has correct path embedded in comment', () => { + test('app has correct path embedded in comment', () => { const assertFile = expectFile('components/from-the-app.js'); assertFile.exists(); // This is the expected output during an classic build. - assertFile.matches(/path:my-app\/components\/from-the-app\.js/, 'has a path comment in app components'); + assertFile.matches(/path@my-app\/components\/from-the-app\.js/, 'has a path comment in app components'); }); test('addon has correct path embedded in comment', () => { expectFile('node_modules/my-preprocessor/package.json').exists(); const assertFile = expectFile('node_modules/my-addon/components/greeting.js'); - assertFile.matches(/\/\/path:my-addon\/components\/from-the-app\.js/, 'has a path comment in app components'); + assertFile.matches(/path@my-addon\/components\/greeting\.js/, 'has a path comment in app components'); }); }); From 94d901023267acb96b1ca1ceeac9ac93b0cedcbc Mon Sep 17 00:00:00 2001 From: Matthew Edwards Date: Thu, 19 May 2022 12:12:18 -0700 Subject: [PATCH 3/6] Move declaration lower --- packages/compat/tests/preprocessors.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/compat/tests/preprocessors.test.ts b/packages/compat/tests/preprocessors.test.ts index c9a4bde17..68709b767 100644 --- a/packages/compat/tests/preprocessors.test.ts +++ b/packages/compat/tests/preprocessors.test.ts @@ -13,8 +13,6 @@ describe('preprocessors tests', function () { beforeAll(async function () { app = Project.emberNew('my-app'); - const PACKAGE_MY_PREPROCESSOR = 'my-preprocessor'; - merge(app.files, { config: { 'targets.js': `module.exports = { browsers: ['last 1 Chrome versions'] }`, @@ -30,6 +28,7 @@ describe('preprocessors tests', function () { }, }); + const PACKAGE_MY_PREPROCESSOR = 'my-preprocessor'; let addonPreprocessor = app.addAddon(PACKAGE_MY_PREPROCESSOR); const INDEX_JS_WITH_PREPROCESSOR = `const { map } = require('broccoli-stew'); From 4807d8b67d1433977f7021cc632bea399e520246 Mon Sep 17 00:00:00 2001 From: Matthew Edwards Date: Thu, 19 May 2022 12:14:50 -0700 Subject: [PATCH 4/6] Remove console.log --- packages/compat/tests/preprocessors.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compat/tests/preprocessors.test.ts b/packages/compat/tests/preprocessors.test.ts index 68709b767..aec0c09f3 100644 --- a/packages/compat/tests/preprocessors.test.ts +++ b/packages/compat/tests/preprocessors.test.ts @@ -93,7 +93,7 @@ module.exports = { tests: false, }, }); - console.log(build.outputPath); + expectFile = expectFilesAt(build.outputPath); }); From d0ebc21772d9b06e94ae23b7a1d09721aec7544f Mon Sep 17 00:00:00 2001 From: Matthew Edwards Date: Thu, 19 May 2022 12:20:42 -0700 Subject: [PATCH 5/6] Fix test setup. preprocessors tests pass --- packages/compat/tests/preprocessors.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/compat/tests/preprocessors.test.ts b/packages/compat/tests/preprocessors.test.ts index aec0c09f3..4ee7c840f 100644 --- a/packages/compat/tests/preprocessors.test.ts +++ b/packages/compat/tests/preprocessors.test.ts @@ -84,7 +84,9 @@ module.exports = { }, }); - addon.addDependency(PACKAGE_MY_PREPROCESSOR); + // We must explicitly pass the addonPreprocessor using the + // name is not sufficient. + addon.addDependency(addonPreprocessor); build = await BuildResult.build(app, { stage: 2, From 4e4d81e9843ebb8a2fd5ea122163b4ab5907cd54 Mon Sep 17 00:00:00 2001 From: Matthew Edwards Date: Fri, 20 May 2022 21:06:40 -0700 Subject: [PATCH 6/6] FIX only namespae preprocessJs tree --- packages/compat/src/v1-addon.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/compat/src/v1-addon.ts b/packages/compat/src/v1-addon.ts index b464a706c..eefdef51a 100644 --- a/packages/compat/src/v1-addon.ts +++ b/packages/compat/src/v1-addon.ts @@ -488,22 +488,26 @@ export default class V1Addon { // applies preprocessors to JS and HBS private transpile(tree: Node) { + // Namespace the tree being passed to preprocessJs with the moduleName + // to mimic classic build tree = buildFunnel(tree, { destDir: this.moduleName }); tree = this.addonInstance.preprocessJs(tree, '/', this.moduleName, { registry: this.addonInstance.registry, }); + // Remove namespacing so that it gets written out to the node_modules + // directory correctly. + tree = buildFunnel(tree, { + srcDir: this.moduleName, + }); + if (this.addonInstance.shouldCompileTemplates() && this.addonInstance.registry.load('template')?.length > 0) { tree = this.app.preprocessRegistry.preprocessTemplates(tree, { registry: this.addonInstance.registry, }); } - tree = buildFunnel(tree, { - srcDir: this.moduleName, - }); - return tree; }