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

Fix ESM exports #78

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
39 changes: 23 additions & 16 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,11 @@

{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 6,
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/naming-convention": [
"warn",
{
"selector": "typeLike",
"format": [
"PascalCase"
]
}
],
"@typescript-eslint/semi": "warn",
"curly": "warn",
"eqeqeq": "warn",
Expand All @@ -27,5 +14,25 @@
"no-unused-expressions": "warn",
"no-duplicate-imports": "warn",
"new-parens": "warn"
}
}
},
"overrides": [
{
"files": ["*.ts"],
"plugins": [
"@typescript-eslint"
],
"parser": "@typescript-eslint/parser",
"rules": {
"@typescript-eslint/naming-convention": [
"warn",
{
"selector": "typeLike",
"format": [
"PascalCase"
]
}
]
}
}
]
}
8 changes: 6 additions & 2 deletions .mocharc.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"ui": "tdd",
"color": true
}
"color": true,
"spec": [
"./lib/cjs/test/*.test.js",
"./lib/esm/test/*.test.js"
]
}
12 changes: 12 additions & 0 deletions build/fix-esm.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env node
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import fs from 'fs/promises';

await fs.writeFile(
new URL('../lib/esm/package.json', import.meta.url),
JSON.stringify({ type: 'module' }, undefined, 2) + '\n'
);
4 changes: 2 additions & 2 deletions build/remove-sourcemap-refs.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ function deleteRefs(dir) {
deleteRefs(filePath);
} else if (path.extname(file) === '.js') {
const content = fs.readFileSync(filePath, 'utf8');
const newContent = content.replace(/\/\/\# sourceMappingURL=[^]+.js.map/, '')
const newContent = content.replace(/\/\/\# sourceMappingURL=[^]+.js.map/, '');
if (content.length !== newContent.length) {
console.log('remove sourceMappingURL in ' + filePath);
fs.writeFileSync(filePath, newContent);
}
} else if (path.extname(file) === '.map') {
fs.unlinkSync(filePath)
fs.unlinkSync(filePath);
console.log('remove ' + filePath);
}
}
Expand Down
22 changes: 13 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
"name": "jsonc-parser",
"version": "3.2.1",
"description": "Scanner and parser for JSON with comments.",
"main": "./lib/umd/main.js",
"typings": "./lib/umd/main.d.ts",
"module": "./lib/esm/main.js",
"main": "./lib/cjs/main.js",
"exports": {
".": {
"import": "./lib/esm/main.js",
"module": "./lib/esm/main.js",
Copy link

@xiaoxiangmoe xiaoxiangmoe Jun 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the meaning of "module" exports?
I didn't see it in nodejs docs and webpack docs. Where is it used for or where is the official doc for it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It tells bundlers to use it, even when the module is required from a CJS file. So it helps reduce bundle size and avoid the dual package hazard.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the "import" condition is more widely used in webpack, vite and node. Why should we add unofficial "module" condition.

"default": "./lib/cjs/main.js"
}
},
"author": "Microsoft Corporation",
"repository": {
"type": "git",
Expand All @@ -25,13 +30,12 @@
"rimraf": "^5.0.5"
},
"scripts": {
"prepack": "npm run clean && npm run compile-esm && npm run test && npm run remove-sourcemap-refs",
"compile": "tsc -p ./src && npm run lint",
"compile-esm": "tsc -p ./src/tsconfig.esm.json",
"prepack": "npm run clean && npm run test && npm run remove-sourcemap-refs",
"compile": "tsc -b && node ./build/fix-esm.mjs && npm run lint",
"remove-sourcemap-refs": "node ./build/remove-sourcemap-refs.js",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that remove-sourcemap-refs job is useless. We can set "sourceMap": false in tsconfig. @aeschli

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That breaks code coverage and source mapping when running tests.

"clean": "rimraf lib",
"watch": "tsc -w -p ./src",
"test": "npm run compile && mocha ./lib/umd/test",
"lint": "eslint src/**/*.ts"
"watch": "tsc -w -b",
"test": "npm run compile && mocha",
"lint": "eslint ."
}
}
6 changes: 3 additions & 3 deletions src/impl/edit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
'use strict';

import { Edit, ParseError, Node, JSONPath, Segment, ModificationOptions } from '../main';
import { format, isEOL } from './format';
import { parseTree, findNodeAtLocation } from './parser';
import { Edit, ParseError, Node, JSONPath, Segment, ModificationOptions } from '../main.js';
import { format, isEOL } from './format.js';
import { parseTree, findNodeAtLocation } from './parser.js';

export function removeProperty(text: string, path: JSONPath, options: ModificationOptions): Edit[] {
return setProperty(text, path, void 0, options);
Expand Down
6 changes: 3 additions & 3 deletions src/impl/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
'use strict';

import { Range, FormattingOptions, Edit, SyntaxKind, ScanError } from '../main';
import { createScanner } from './scanner';
import { cachedSpaces, cachedBreakLinesWithSpaces, supportedEols, SupportedEOL } from './string-intern';
import { Range, FormattingOptions, Edit, SyntaxKind, ScanError } from '../main.js';
import { createScanner } from './scanner.js';
import { cachedSpaces, cachedBreakLinesWithSpaces, supportedEols, SupportedEOL } from './string-intern.js';

export function format(documentText: string, range: Range | undefined, options: FormattingOptions): Edit[] {
let initialIndentLevel: number;
Expand Down
4 changes: 2 additions & 2 deletions src/impl/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';

import { createScanner } from './scanner';
import { createScanner } from './scanner.js';
import {
JSONPath,
JSONVisitor,
Expand All @@ -17,7 +17,7 @@ import {
ScanError,
Segment,
SyntaxKind
} from '../main';
} from '../main.js';

namespace ParseOptions {
export const DEFAULT = {
Expand Down
2 changes: 1 addition & 1 deletion src/impl/scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';

import { ScanError, SyntaxKind, JSONScanner } from '../main';
import { ScanError, SyntaxKind, JSONScanner } from '../main.js';

/**
* Creates a JSON scanner on the given text.
Expand Down
8 changes: 4 additions & 4 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
*--------------------------------------------------------------------------------------------*/
'use strict';

import * as formatter from './impl/format';
import * as edit from './impl/edit';
import * as scanner from './impl/scanner';
import * as parser from './impl/parser';
import * as formatter from './impl/format.js';
import * as edit from './impl/edit.js';
import * as scanner from './impl/scanner.js';
import * as parser from './impl/parser.js';

/**
* Creates a JSON scanner on the given text.
Expand Down
10 changes: 5 additions & 5 deletions src/test/edit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
'use strict';

import * as assert from 'assert';
import { FormattingOptions, Edit, ModificationOptions, modify } from '../main';
import { FormattingOptions, Edit, ModificationOptions, modify } from '../main.js';

suite('JSON - edits', () => {

function assertEdit(content: string, edits: Edit[], expected: string) {
assert(edits);
assert.ok(edits);
let lastEditOffset = content.length;
for (let i = edits.length - 1; i >= 0; i--) {
let edit = edits[i];
assert(edit.offset >= 0 && edit.length >= 0 && edit.offset + edit.length <= content.length);
assert(typeof edit.content === 'string');
assert(lastEditOffset >= edit.offset + edit.length); // make sure all edits are ordered
assert.ok(edit.offset >= 0 && edit.length >= 0 && edit.offset + edit.length <= content.length);
assert.ok(typeof edit.content === 'string');
assert.ok(lastEditOffset >= edit.offset + edit.length); // make sure all edits are ordered
lastEditOffset = edit.offset;
content = content.substring(0, edit.offset) + edit.content + content.substring(edit.offset + edit.length);
}
Expand Down
10 changes: 5 additions & 5 deletions src/test/format.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
'use strict';

import * as assert from 'assert';
import * as Formatter from '../impl/format';
import { Range } from '../main';
import * as Formatter from '../impl/format.js';
import { Range } from '../main.js';

suite('JSON - formatter', () => {

Expand All @@ -25,9 +25,9 @@ suite('JSON - formatter', () => {

for (let i = edits.length - 1; i >= 0; i--) {
const edit = edits[i];
// assert(edit.offset >= 0 && edit.length >= 0 && edit.offset + edit.length <= content.length);
// assert(typeof edit.content === 'string');
// assert(lastEditOffset >= edit.offset + edit.length); // make sure all edits are ordered
// assert.ok(edit.offset >= 0 && edit.length >= 0 && edit.offset + edit.length <= content.length);
// assert.ok(typeof edit.content === 'string');
// assert.ok(lastEditOffset >= edit.offset + edit.length); // make sure all edits are ordered
lastEditOffset = edit.offset;
content = content.substring(0, edit.offset) + edit.content + content.substring(edit.offset + edit.length);
}
Expand Down
8 changes: 4 additions & 4 deletions src/test/json.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as assert from 'assert';
import {
SyntaxKind, createScanner, parse, getLocation, Node, ParseError, parseTree, ParseErrorCode,
ParseOptions, Segment, findNodeAtLocation, getNodeValue, getNodePath, ScanError, visit, JSONVisitor, JSONPath
} from '../main';
} from '../main.js';

function assertKinds(text: string, ...kinds: SyntaxKind[]): void {
var scanner = createScanner(text);
Expand Down Expand Up @@ -43,7 +43,7 @@ function assertInvalidParse(input: string, expected: any, options?: ParseOptions
var errors: ParseError[] = [];
var actual = parse(input, errors, options);

assert(errors.length > 0);
assert.ok(errors.length > 0);
assert.deepStrictEqual(actual, expected);
}

Expand Down Expand Up @@ -117,7 +117,7 @@ function assertLocation(input: string, expectedSegments: Segment[], expectedNode
var offset = input.indexOf('|');
input = input.substring(0, offset) + input.substring(offset + 1, input.length);
var actual = getLocation(input, offset);
assert(actual);
assert.ok(actual);
assert.deepStrictEqual(actual.path, expectedSegments, input);
assert.strictEqual(actual.previousNode && actual.previousNode.type, expectedNodeType, input);
assert.strictEqual(actual.isAtPropertyKey, expectedCompleteProperty, input);
Expand All @@ -127,7 +127,7 @@ function assertMatchesLocation(input: string, matchingSegments: Segment[], expec
var offset = input.indexOf('|');
input = input.substring(0, offset) + input.substring(offset + 1, input.length);
var actual = getLocation(input, offset);
assert(actual);
assert.ok(actual);
assert.strictEqual(actual.matches(matchingSegments), expectedResult);
}

Expand Down
16 changes: 0 additions & 16 deletions src/tsconfig.json

This file was deleted.

7 changes: 7 additions & 0 deletions tsconfig.cjs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.esm.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "./lib/cjs"
}
}
10 changes: 6 additions & 4 deletions src/tsconfig.esm.json → tsconfig.esm.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
{
"include": ["src"],
"compilerOptions": {
"target": "es2020",
"module": "es6",
"moduleResolution": "node",
"module": "esnext",
"moduleResolution": "node16",
"sourceMap": true,
"declaration": true,
"stripInternal": true,
"outDir": "../lib/esm",
"outDir": "./lib/esm",
"rootDir": "./src",
"strict": true,
"preserveConstEnums": true,
"lib": [
"es2020"
]
}
}
}
7 changes: 7 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.cjs.json" },
{ "path": "./tsconfig.esm.json" }
]
}