Skip to content

Commit

Permalink
Refactor template-transform-plugin to depend on babel-plugin-stage1-i…
Browse files Browse the repository at this point in the history
…nline-hbs
  • Loading branch information
Matthew Edwards committed Jun 1, 2022
1 parent cd75c21 commit 2516c76
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 89 deletions.
101 changes: 28 additions & 73 deletions packages/addon-dev/src/template-transform-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,82 +1,37 @@
import type * as Babel from '@babel/core';
import type { types as t } from '@babel/core';
import type { NodePath } from '@babel/traverse';
import { preprocess, print } from '@glimmer/syntax';
import make from '@embroider/core/src/babel-plugin-stage1-inline-hbs';
import { TemplateCompiler, TemplateCompilerParams } from '@embroider/core';
import { getEmberExports } from '@embroider/core/src/load-ember-template-compiler';
import { EmberENV } from '@embroider/core';

type TemplateTransform = () => { name: string; visitor: {} };

export type TemplateTransformPlugin = TemplateTransform | string;
export interface Options {
astTransforms?: Array<string | Function>;
astTransforms: TemplateTransformPlugin[] | undefined;
compilerPath: string;
EmberENV: EmberENV;
}

interface State {
opts: Options;
localName: string | undefined;
function resolvePlugins(plugins: TemplateTransformPlugin[]) {
return plugins.map((somePlugin: TemplateTransformPlugin) => {
// If it's a string attempt to resolve the path to a module.
return typeof somePlugin === 'string'
? require(somePlugin) // eslint-disable-line @typescript-eslint/no-require-imports
: somePlugin;
});
}

export default function main(babel: typeof Babel) {
let t = babel.types;

return {
visitor: {
ImportDeclaration(path: NodePath<t.ImportDeclaration>, state: State) {
if (path.node.source.value !== 'ember-cli-htmlbars') {
return;
}

const specifier = path.node.specifiers.find(
(s) =>
t.isImportSpecifier(s) &&
t.isIdentifier(s.imported) &&
s.imported.name === 'hbs'
);

if (!specifier) {
return;
}

state.localName = specifier.local.name;
},
CallExpression(path: NodePath<t.CallExpression>, state: State) {
const localName = state.localName;

if (!t.isIdentifier(path.node.callee)) {
return;
}

const callee = path.node.callee;

if (!localName || callee.name !== localName) {
return;
}
export default make((options: Options) => {
let { compilerPath, astTransforms: somePlugins = [], ...opts } = options;
const astTransforms: TemplateTransform[] = resolvePlugins(somePlugins);

let template = (path.node.arguments[0] as t.StringLiteral).value;

let options = {
astTransforms: [],
...state.opts,
};

const astTransforms = options.astTransforms.map((maybeFunc) => {
// If it's a string attempt to resolve the path to a module.
return typeof maybeFunc === 'string'
? require(maybeFunc) // eslint-disable-line @typescript-eslint/no-require-imports
: maybeFunc;
});

if (astTransforms.length < 1) {
return;
}

const ast = preprocess(template, {
plugins: {
ast: [...astTransforms],
},
});

const augmentedTemplate = print(ast);

// Create a new stringLiteral with the augmentedTemplate
path.node.arguments[0] = t.stringLiteral(augmentedTemplate);
},
const params: TemplateCompilerParams = {
loadEmberTemplateCompiler: () => getEmberExports(compilerPath),
plugins: {
ast: astTransforms,
},
...opts,
};
}

return new TemplateCompiler(params);
});
44 changes: 28 additions & 16 deletions packages/addon-dev/tests/template-transform-plugin.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { allBabelVersions } from '@embroider/test-support';
import { Options } from '../src/template-transform-plugin';
import { hbsToJS } from '@embroider/shared-internals';
import {
allBabelVersions,
emberTemplateCompilerPath,
} from '@embroider/test-support';
import {
TemplateTransformPlugin,
Options,
} from '../src/template-transform-plugin';
import { hbsToJS } from '@embroider/core';
import { AST } from '@glimmer/syntax';
import { join } from 'path';
import tmp from 'tmp';
Expand All @@ -27,8 +33,15 @@ describe('template-transform-plugin', () => {
};
}

function setupPlugins(options?: Options) {
plugins = [[templateTransformBabelPlugin, options]];
function setupPlugins(options?: {
astTransforms: TemplateTransformPlugin[];
}) {
const opts: Options = {
astTransforms: options?.astTransforms,
compilerPath: emberTemplateCompilerPath(),
EmberENV: {},
};
plugins = [[templateTransformBabelPlugin, opts]];
}

allBabelVersions({
Expand All @@ -40,7 +53,6 @@ describe('template-transform-plugin', () => {
createTests(transform) {
afterEach(function () {
plugins = undefined;
// options = undefined;
});

test('no-op', () => {
Expand Down Expand Up @@ -87,15 +99,15 @@ describe('template-transform-plugin', () => {
const someFile = tmp.fileSync();

const contents = `module.exports = function reverseTransform() {
return {
name: 'reverse-transform',
visitor: {
ElementNode(node) {
node.tag = node.tag.split('').reverse().join('');
},
},
};
}`;
return {
name: 'reverse-transform',
visitor: {
ElementNode(node) {
node.tag = node.tag.split('').reverse().join('');
},
},
};
}`;

writeFileSync(someFile.name, contents, 'utf8');

Expand Down Expand Up @@ -123,7 +135,7 @@ describe('template-transform-plugin', () => {
});

const code = `import { hbs as render } from 'ember-cli-htmlbars';
export default render('<span>{{@phrase}}</span>');`;
export default render('<span>{{@phrase}}</span>');`;

let output = transform(code);

Expand Down

0 comments on commit 2516c76

Please sign in to comment.