diff --git a/runtime/JavaScript/package.json b/runtime/JavaScript/package.json index 70b426f652..972df11603 100644 --- a/runtime/JavaScript/package.json +++ b/runtime/JavaScript/package.json @@ -4,7 +4,7 @@ "type": "module", "description": "JavaScript runtime for ANTLR4", "browser": "dist/antlr4.web.js", - "main": "dist/antlr4.node.js", + "main": "dist/antlr4.node.mjs", "types": "src/antlr4/index.d.ts", "repository": "antlr/antlr4.git", "keywords": [ @@ -47,5 +47,21 @@ }, "engines": { "node": ">=16" + }, + "exports": { + ".": { + "node": { + "types": "src/index.node.d.ts", + "import": "./dist/antlr4.node.mjs", + "require": "./dist/antlr4.node.cjs", + "default": "./dist/antlr4.node.mjs" + }, + "browser": { + "types": "src/index.web.d.ts", + "import": "./dist/antlr4.web.mjs", + "require": "./dist/antlr4.web.cjs", + "default": "./dist/antlr4.web.mjs" + } + } } } diff --git a/runtime/JavaScript/spec/imports/NodeCommonJSImportSpec.cjs b/runtime/JavaScript/spec/imports/NodeCommonJSImportSpec.cjs new file mode 100644 index 0000000000..302a69199a --- /dev/null +++ b/runtime/JavaScript/spec/imports/NodeCommonJSImportSpec.cjs @@ -0,0 +1,8 @@ +"use strict"; + +const antlr4 = require("antlr4"); +describe('Antlr4 Node CommonJs', () => { + it('should use the CommonJS module on Node.js', () => { + expect(antlr4).toBeDefined(); + }); +}); diff --git a/runtime/JavaScript/spec/imports/NodeEsmImportSpec.mjs b/runtime/JavaScript/spec/imports/NodeEsmImportSpec.mjs new file mode 100644 index 0000000000..2cc170db2b --- /dev/null +++ b/runtime/JavaScript/spec/imports/NodeEsmImportSpec.mjs @@ -0,0 +1,8 @@ +import * as antlr4 from 'antlr4' + +describe('Antlr4 Node Esm', () => { + it('should use the Esm module on Node.js', () => { + expect(antlr4).toBeDefined(); + }); +}); +export {}; diff --git a/runtime/JavaScript/spec/support/jasmine.json b/runtime/JavaScript/spec/support/jasmine.json index b62f0ad643..0217ee8064 100644 --- a/runtime/JavaScript/spec/support/jasmine.json +++ b/runtime/JavaScript/spec/support/jasmine.json @@ -1,6 +1,7 @@ { "spec_dir": "spec", "spec_files": [ + "**/*Spec.[c|m]*js", "**/*Spec.js" ], "helpers": [ diff --git a/runtime/JavaScript/webpack.config.js b/runtime/JavaScript/webpack.config.js index b140698641..51890c7ca5 100644 --- a/runtime/JavaScript/webpack.config.js +++ b/runtime/JavaScript/webpack.config.js @@ -5,68 +5,63 @@ import {fileURLToPath} from "url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -const nodeConfig = { + +const buildConfig = ( platform, extensions ) => ({ mode: "production", - entry: './src/antlr4/index.node.js', + entry: `./src/antlr4/index.${platform}.js`, output: { path: path.resolve(__dirname, 'dist'), - filename: 'antlr4.node.js', - chunkFormat: "module", + filename: `antlr4.${platform}.${extensions}`, + chunkFormat: extensions === "mjs" ? "module" : "commonjs", library: { - type: "module" + type: extensions === "mjs" ? "module" : "commonjs" } }, - resolve: { - extensions: [ '.js'] - }, - target: "node", + + ...(platform === 'web' && { module: { - rules: [{ - test: /\.js$/, - exclude: /node_modules/, - use: [ 'babel-loader' ] - }] - }, - plugins: [ new ESLintPlugin() ], - experiments: { - outputModule: true - }, - devtool: "source-map" -}; + rules: [{ + test: /\.js$/, + exclude: [ /node_modules/, path.resolve(__dirname, "src/FileStream.js") ], + use: [ 'babel-loader' ] + }] + }, + performance: { + maxAssetSize: 512000, + maxEntrypointSize: 512000 + }, + resolve: { + extensions: [ '.js'], + fallback: { + fs: false + } + }, + }), -const webConfig = { - mode: "production", - entry: './src/antlr4/index.web.js', - output: { - path: path.resolve(__dirname, 'dist'), - filename: 'antlr4.web.js', - library: { - type: "module" - } - }, - resolve: { - extensions: [ '.js'], - fallback: { - fs: false - } - }, - target: "web", - module: { - rules: [{ - test: /\.js$/, - exclude: [ /node_modules/, path.resolve(__dirname, "src/FileStream.js") ], - use: [ 'babel-loader' ] - }] - }, - performance: { - maxAssetSize: 512000, - maxEntrypointSize: 512000 - }, + ...(platform === 'node' && { + module: { + rules: [{ + test: /\.js$/, + exclude: /node_modules/, + use: [ 'babel-loader' ] + }] + }, + resolve: { + extensions: [ '.js'], + }, + }), + target: platform, plugins: [ new ESLintPlugin() ], + devtool: "source-map", experiments: { - outputModule: true + outputModule: extensions === "mjs" }, - devtool: "source-map" -}; +}) + -export default [ nodeConfig, webConfig ]; +export default [ + buildConfig("node", "cjs"), + buildConfig("node", "mjs"), + buildConfig("web", "cjs"), + buildConfig("web", "mjs"), +];