Skip to content

Commit

Permalink
fix(rollup): Correctly generate source maps
Browse files Browse the repository at this point in the history
  • Loading branch information
lgollut committed Aug 16, 2024
1 parent aed83e7 commit cf22160
Show file tree
Hide file tree
Showing 13 changed files with 86 additions and 45 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions packages/ast-parsers/src/__tests__/js-parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import { jsParser } from '../js-parser';

describe('jsParser', () => {
const source = 'const value = 1;';
const file = 'test.js';
it('should return the source if no valid visitor is provided', () => {
expect(jsParser(source, 'test.js', {}).code).toContain(source);
expect(jsParser({ source, file, visitors: {} }).code).toContain(source);
});

it('should transform the source if visitor is a valid visitor object', () => {
Expand All @@ -23,7 +24,7 @@ describe('jsParser', () => {
},
};

expect(jsParser(source, 'test.js', visitor).code).toMatch(
expect(jsParser({ source, file, visitors: visitor }).code).toMatch(
'const value = 2;',
);
});
Expand Down Expand Up @@ -57,7 +58,7 @@ describe('jsParser', () => {
},
];

expect(jsParser(source, 'test.js', visitors).code).toMatch(
expect(jsParser({ source, file, visitors }).code).toMatch(
'const expected = 2;',
);
});
Expand Down
25 changes: 16 additions & 9 deletions packages/ast-parsers/src/js-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,46 +8,50 @@ import { isFunction } from './utils';
import type { Node } from 'estree';

export type AstParserVisitors = Visitor | Visitor[] | undefined;
export type JsParserOptions = {
source: string;
file: string;
visitors?: AstParserVisitors;
};

/**
* Create an AST representation of the provided source and use the
* visitor object to transform it if provided
*/
export function jsParser(
source: string,
file: string,
visitors?: AstParserVisitors,
) {
export function jsParser({ source, file, visitors }: JsParserOptions) {
if (!visitors) {
/* eslint-disable-next-line no-console */
console.warn(
'[esbuildPluginAst]: No javascript visitor provided, the plugin will have no effect.',
);
return { code: source };
return { code: source, ast: null, map: null };
}

const ast = Parser.parse(source, {
ecmaVersion: 'latest',
sourceType: 'module',
locations: true,
}) as Node;

return transformer({ ast, file, visitors });
return transformer({ ast, file, visitors, source });
}

type TransformerOptions<N extends Node> = {
ast: N;
file: string;
visitors?: AstParserVisitors;
source: string;
};

export function transformer<N extends Node>({
ast,
file,
visitors,
source,
}: TransformerOptions<N>) {
const visitorArray = Array.isArray(visitors) ? visitors : [visitors];

let newAst = ast;
let newAst = structuredClone(ast);

for (const visitor of visitorArray) {
if (
Expand All @@ -61,6 +65,9 @@ export function transformer<N extends Node>({
}

const map = new SourceMapGenerator({ file });
map.setSourceContent(file, source);

const code = generate(newAst, { sourceMap: map });

return { code: generate(newAst, { sourceMap: map }), ast: newAst, map };
return { code, ast: newAst, map };
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ describe('parseSelectorArguments', () => {

const options = { prefix };

updateLiterals(originalNode, prefixer as Prefixer, options);
updateLiterals({
node: originalNode,
prefixer: prefixer as Prefixer,
options,
});

expect(prefixer).toHaveBeenCalledWith(originalNode.value, options);
});
Expand All @@ -50,7 +54,11 @@ describe('parseSelectorArguments', () => {

const options = { prefix };

updateLiterals(originalNode, prefixer as Prefixer, options);
updateLiterals({
node: originalNode,
prefixer: prefixer as Prefixer,
options,
});

expect(prefixer).toHaveBeenNthCalledWith(
1,
Expand Down
4 changes: 2 additions & 2 deletions packages/class-prefixer-ast-visitor/src/create-visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const createVisitor = (config?: PrefixerOptions): Visitor => ({
* Handle `classPrefixer` expression
*/
if (node.callee.name === 'classPrefixer') {
return parseClassArguments(node.arguments[0], config);
return parseClassArguments(node.arguments[0], config, node.loc);
}

/**
Expand All @@ -31,7 +31,7 @@ export const createVisitor = (config?: PrefixerOptions): Visitor => ({
);
}

return parseSelectorArguments(node.arguments[0], config);
return parseSelectorArguments(node.arguments[0], config, node.loc);
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { prefixer, PrefixerOptions } from '@liip/class-prefixer-core';

import { updateLiterals } from './update-literals';

import type { Node } from 'estree';
import type { Node, SourceLocation } from 'estree';

const selectorRegex = /[^a-zA-Z\d\s:_-]/;

Expand All @@ -13,6 +13,7 @@ const selectorRegex = /[^a-zA-Z\d\s:_-]/;
export function parseClassArguments<N extends Node>(
node: N,
options?: PrefixerOptions,
loc?: SourceLocation | null,
): N {
if (node.type === 'CallExpression' && node.arguments) {
return {
Expand Down Expand Up @@ -53,7 +54,7 @@ export function parseClassArguments<N extends Node>(
);
}

return updateLiterals(node, prefixer, options) as N;
return updateLiterals({ node, prefixer, options, loc }) as N;
}

return node;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,27 @@ import { selectorPrefixer, PrefixerOptions } from '@liip/class-prefixer-core';

import { updateLiterals } from './update-literals';

import type { Node } from 'estree';
import type { Node, SourceLocation } from 'estree';

/**
* Parse the argument to produce prefixed selectors. We only accept
* string argument as selectors
*/
export function parseSelectorArguments(node: Node, options?: PrefixerOptions) {
export function parseSelectorArguments(
node: Node,
options?: PrefixerOptions,
loc?: SourceLocation | null,
) {
if (node.type !== 'TemplateLiteral' && node.type !== 'Literal') {
throw new Error(
`"selectorPrefixer" only accept string or template literal argument. You passed ${node.type}`,
);
}

return updateLiterals(node, selectorPrefixer, options);
return updateLiterals({
node,
prefixer: selectorPrefixer,
options,
loc,
});
}
22 changes: 16 additions & 6 deletions packages/class-prefixer-ast-visitor/src/update-literals.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
import type { Prefixer, PrefixerOptions } from '@liip/class-prefixer-core';
import type { Literal, TemplateLiteral } from 'estree';
import type { Literal, SourceLocation, TemplateLiteral } from 'estree';

export type UpdateLiteralsOptions = {
node: Literal | TemplateLiteral;
prefixer: Prefixer;
options?: PrefixerOptions;
loc?: SourceLocation | null;
};

/**
* Update `Literal` and `TemplateLiteral` nodes with prefixed value
*/
export function updateLiterals(
node: Literal | TemplateLiteral,
prefixer: Prefixer,
options?: PrefixerOptions,
) {
export function updateLiterals({
node,
prefixer,
options,
loc,
}: UpdateLiteralsOptions) {
if (node.type === 'Literal' && typeof node.value === 'string') {
const value: string = prefixer(node.value, options);

return {
...node,
value,
raw: `'${value}'`,
loc,
};
}

if (node.type === 'TemplateLiteral') {
const newNode: TemplateLiteral = {
...node,
loc,
quasis: node.quasis.map((node) => ({
...node,
value: {
Expand Down
2 changes: 1 addition & 1 deletion packages/esbuild-plugin-ast-vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"hash-sum": "^2.0.0"
},
"peerDependencies": {
"@liip/esbuild-plugin-ast": "0.3.x",
"@liip/esbuild-plugin-ast": "0.4.x",
"esbuild": "0.19.x"
}
}
12 changes: 10 additions & 2 deletions packages/esbuild-plugin-ast-vue/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@ export function esbuildAstParserVue({
}

return {
contents: jsParser(code, args.path, availableVisitors).code,
contents: jsParser({
source: code,
file: args.path,
visitors: availableVisitors,
}).code,
errors: error,
resolveDir: dirname,
loader: 'js',
Expand All @@ -158,7 +162,11 @@ export function esbuildAstParserVue({
});

return {
contents: jsParser(code, args.path, templateVisitor).code,
contents: jsParser({
source: code,
file: args.path,
visitors: templateVisitor,
}).code,
pluginData: { code },
errors,
resolveDir: dirname,
Expand Down
2 changes: 1 addition & 1 deletion packages/esbuild-plugin-ast/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export function esbuildAstParser({
}

return {
contents: jsParser(source, args.path, visitors).code,
contents: jsParser({ source, file: args.path, visitors }).code,
loader: 'js',
};
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { join } from 'node:path';

import { rollup } from 'rollup';

import astTransform, { PluginAstTransformOptions } from '../plugin';
import { astTransform, PluginAstTransformOptions } from '../plugin';

describe('astTransform Plugin', () => {
const placeholder = 'astParser';
Expand Down Expand Up @@ -63,6 +63,7 @@ describe('astTransform Plugin', () => {
type: 'Literal',
value: argument,
raw: `"${argument}"`,
loc: node.loc,
};
}

Expand Down
20 changes: 8 additions & 12 deletions packages/rollup-plugin-ast-transform/src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { AstParserVisitors, transformer } from '@liip/ast-parsers';
import { basename } from 'node:path';

import { AstParserVisitors, jsParser } from '@liip/ast-parsers';
import { createFilter, FilterPattern } from '@rollup/pluginutils';
import { Plugin } from 'rollup';

Expand All @@ -8,7 +10,7 @@ export type PluginAstTransformOptions = {
visitors: AstParserVisitors;
};

export default function astTransform({
export function astTransform({
include,
exclude,
visitors,
Expand All @@ -22,19 +24,13 @@ export default function astTransform({
return null;
}

const ast = this.parse(source, { allowReturnOutsideFunction: true });

const {
code,
ast: transformedAst,
map,
} = transformer({
ast,
file: id,
const { code, map } = jsParser({
source,
file: basename(id),
visitors,
});

return { code, ast: transformedAst, map: map.toString() };
return { code, map: map?.toString() ?? null };
},
};
}

0 comments on commit cf22160

Please sign in to comment.