Skip to content

Commit

Permalink
feat: set specific source file path in the dts source-maps (#2311)
Browse files Browse the repository at this point in the history
  • Loading branch information
tzachbon authored Feb 7, 2022
1 parent 04456e6 commit 46ccd26
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 6 deletions.
4 changes: 3 additions & 1 deletion packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ export interface BuildOptions {
minify?: boolean;
/** should generate .d.ts definitions for every stylesheet */
dts?: boolean;
/** should generate .d.ts.map files for every .d.ts mapping back to the source .st.css */
/** should generate .d.ts.map files for every .d.ts mapping back to the source .st.css.
* It will use the origin file path unless `outputSources` is true, then it will use the outputted file path as the source-map source.
*/
dtsSourceMap?: boolean;
/** should emit diagnostics */
diagnostics?: boolean;
Expand Down
7 changes: 6 additions & 1 deletion packages/cli/src/build-single-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,12 @@ export function buildSingleFile({
// .d.ts.map
// if not explicitly defined, assumed true with "--dts" parent scope
if (dtsSourceMap !== false) {
const dtsMappingContent = generateDTSSourceMap(dtsContent, res.meta);
const dtsMappingContent = generateDTSSourceMap(
dtsContent,
res.meta,
relative(dirname(outSrcPath), dirname(outputSources ? outSrcPath : filePath))
);

const dtsMapPath = outSrcPath + '.d.ts.map';

generated.add(dtsMapPath);
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/config/resolve-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function getCliArguments(): Arguments<CliArguments> {
.option('dtsSourceMap', {
type: 'boolean',
description:
'output source maps for stylable definition files for sources (.st.css.d.ts.map)',
'output source maps for stylable definition files for sources (.st.css.d.ts.map). It will use the origin file path unless `--stcss` is set, then it will use the outputted file path as the source-map source',
defaultDescription: 'true if "--dts" option is enabled, otherwise false',
})
.option('useNamespaceReference', {
Expand Down
49 changes: 49 additions & 0 deletions packages/cli/test/cli.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,55 @@ describe('Stylable Cli', function () {
).to.equal(true);
});

it('build .st.css.d.ts source-map and target the source file path relatively', () => {
const srcContent = '.root{color:red}';
populateDirectorySync(tempDir.path, {
'package.json': `{"name": "test", "version": "0.0.0"}`,
src: { 'style.st.css': srcContent },
});

runCliSync(['--rootDir', tempDir.path, '--srcDir', './src', '--outDir', 'dist', '--dts']);

const dirContent = loadDirSync(tempDir.path);
const dtsSourceMapContent = dirContent['dist/style.st.css.d.ts.map'];

expect(
dtsSourceMapContent.startsWith('{\n "version": 3,\n "file": "style.st.css.d.ts"')
).to.equal(true);
expect(dtsSourceMapContent).to.contain(
`"sources": [\n ${JSON.stringify(join('..', 'src', 'style.st.css'))}\n ]`
);
});

it('build .st.css.d.ts source-map and target the output source file path', () => {
const srcContent = '.root{color:red}';
populateDirectorySync(tempDir.path, {
'package.json': `{"name": "test", "version": "0.0.0"}`,
src: { 'style.st.css': srcContent },
'stylable.config.js': `
exports.stcConfig = {
options: {
outDir: './dist',
srcDir: './src',
outputSources: true,
cjs: false,
dts: true,
}
};
`,
});

runCliSync(['--rootDir', tempDir.path]);

const dirContent = loadDirSync(tempDir.path);
const dtsSourceMapContent = dirContent['dist/style.st.css.d.ts.map'];

expect(
dtsSourceMapContent.startsWith('{\n "version": 3,\n "file": "style.st.css.d.ts"')
).to.equal(true);
expect(dtsSourceMapContent).to.contain(`"sources": [\n "style.st.css"\n ]`);
});

it('build .st.css.d.ts alongside source files with source-maps on by default (config file)', () => {
const srcContent = '.root{color:red}';
populateDirectorySync(tempDir.path, {
Expand Down
10 changes: 7 additions & 3 deletions packages/module-utils/src/generate-dts-sourcemaps.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { basename } from 'path';
import { basename, join } from 'path';
import { ClassSymbol, StylableMeta, valueMapping } from '@stylable/core';
import { STSymbol, CSSKeyframes } from '@stylable/core/dist/features';
import { processDeclarationFunctions } from '@stylable/core/dist/process-declaration-functions';
Expand Down Expand Up @@ -240,7 +240,11 @@ function getClassSourceName(targetName: string, classTokens: ClassesToken): stri
return;
}

export function generateDTSSourceMap(dtsContent: string, meta: StylableMeta) {
export function generateDTSSourceMap(
dtsContent: string,
meta: StylableMeta,
sourceDirPath?: string
) {
const tokens = tokenizeDTS(dtsContent);
const mapping: Record<number, LineMapping> = {};
const lines = dtsContent.split('\n');
Expand Down Expand Up @@ -312,7 +316,7 @@ export function generateDTSSourceMap(dtsContent: string, meta: StylableMeta) {
{
version: 3,
file: `${stylesheetName}.d.ts`,
sources: [stylesheetName],
sources: [sourceDirPath ? join(sourceDirPath, stylesheetName) : stylesheetName],
names: [],
mappings: Object.values(mapping)
.map((segment) => (segment.length ? segment.map((s) => encode(s)).join(',') : ''))
Expand Down
20 changes: 20 additions & 0 deletions packages/module-utils/test/sourcemap.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { generateStylableResult } from '@stylable/core-test-kit';
import { generateDTSSourceMap, generateDTSContent } from '@stylable/module-utils';
import { expect } from 'chai';
import deindent from 'deindent';
import { join } from 'path';
import { SourceMapConsumer } from 'source-map';

function getPosition(content: string, query: string) {
Expand Down Expand Up @@ -42,6 +43,8 @@ describe('.d.ts source-maps', () => {
const dtsText = generateDTSContent(res);
const sourcemapText = generateDTSSourceMap(dtsText, res.meta);

expect(JSON.parse(sourcemapText).sources).to.eql(['entry.st.css']);

sourceMapConsumer = await new SourceMapConsumer(sourcemapText);
const originalPosition = sourceMapConsumer.originalPositionFor(
getPosition(dtsText, 'root":') // source mapping starts after the first double quote
Expand All @@ -50,6 +53,23 @@ describe('.d.ts source-maps', () => {
expect(originalPosition).to.eql({ line: 1, column: 0, source: 'entry.st.css', name: null });
});

it('should generate source maps and set specific file path as the source file path', () => {
const res = generateStylableResult({
entry: `/entry.st.css`,
files: {
'/entry.st.css': {
namespace: 'entry',
content: ``,
},
},
});

const dtsText = generateDTSContent(res);
const sourcemapText = generateDTSSourceMap(dtsText, res.meta, 'src');

expect(JSON.parse(sourcemapText).sources).to.eql([join('src', 'entry.st.css')]);
});

it('maps the "root" class in the ".d.ts" to its position in the original ".st.css" file', async () => {
const res = generateStylableResult({
entry: `/entry.st.css`,
Expand Down

0 comments on commit 46ccd26

Please sign in to comment.