diff --git a/Makefile b/Makefile
index c99785ab..51654be3 100644
--- a/Makefile
+++ b/Makefile
@@ -40,7 +40,7 @@ check: ## Run unit tests and calculate coverage
.PHONY: check-pr
check-pr: ## Run additional pull request tests, linter, and calculate coverage
- cd src && $(MAKE) lint && $(MAKE) check && $(MAKE) check-packages
+ cd src && $(MAKE) lint && $(MAKE) check && $(MAKE) check-packages && $(MAKE) check-module
.PHONY: clean
clean: ## Remove Wasm R build
diff --git a/src/.eslintrc.js b/src/.eslintrc.js
index 391d9882..0a580c54 100644
--- a/src/.eslintrc.js
+++ b/src/.eslintrc.js
@@ -25,7 +25,8 @@ module.exports = {
"jest.config.js",
"tests/webr.config.js",
"tests/scripts/proxy-worker.worker.js",
- "tests/packages.config.js"
+ "tests/packages.config.js",
+ "tests/module"
],
plugins: ["@typescript-eslint", "jest", "jsdoc", "react"],
rules: {
diff --git a/src/Makefile b/src/Makefile
index 91baa996..d3bf296d 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -8,7 +8,8 @@ HTML_TEMPLATES = repl.html
HTML_INDEX = repl.html
TS_SOURCES = $(shell find $(ROOT) \
- -not \( -path '$(ROOT)/node_modules' -prune \) \
+ -not \( -path '*/node_modules' -prune \) \
+ -not \( -path '*/tests/module' -prune \) \
-not \( -path '$(PKG_DIST)' -prune \) \
-name '*.ts' -o -name '*.tsx')
@@ -53,6 +54,10 @@ check: $(DIST)
check-packages: $(DIST)
npx node ./node_modules/jest/bin/jest.js --config tests/packages.config.js
+.PHONY: check-module
+check-module: $(DIST)
+ npx node tests/module/test.js
+
node_modules: package.json
npm ci
touch $@
diff --git a/src/esbuild.ts b/src/esbuild.ts
index 0ab56f4c..334327da 100644
--- a/src/esbuild.ts
+++ b/src/esbuild.ts
@@ -4,60 +4,64 @@ import http from 'http';
let serve = false;
let prod = false;
-let pkg = true;
if (process.argv.some((x) => x === '--serve')) {
serve = true;
- pkg = false;
}
if (process.argv.some((x) => x === '--prod')) {
prod = true;
}
-function build(input: string, output: string, platform: esbuild.Platform, minify: boolean) {
+function build(input: string, options: any) {
return esbuild.context({
assetNames: 'assets/[name]-[hash]',
bundle: true,
entryPoints: [input],
- external: ['worker_threads', 'path', 'fs', 'ws'],
+ external: ['worker_threads', 'path', 'fs', 'ws', 'url', 'child_process', 'http', 'https', 'crypto'],
loader: {
'.jpg': 'file',
'.png': 'file',
'.gif': 'file',
},
mainFields: ['main', 'module'],
- minify: minify,
- outfile: output,
- platform: platform,
plugins: [
cssModulesPlugin({
inject: (cssContent, digest) => `console.log("${cssContent}", "${digest}")`,
})
],
sourcemap: true,
- target: ['es2020', 'node12'],
define: {
'process.env.NODE_ENV': prod ? '"production"' : '"development"',
},
+ ...options,
});
}
-const outputs = {
- browser: [
- build('repl/App.tsx', '../dist/repl.mjs', 'browser', prod),
- build('webR/webr-worker.ts', '../dist/webr-worker.js', 'node', true),
- build('webR/webr-main.ts', '../dist/webr.mjs', 'neutral', prod),
- ],
- npm: [
- build('webR/webr-worker.ts', './dist/webr-worker.js', 'node', true),
- build('webR/webr-main.ts', './dist/webr.cjs', 'node', prod),
- build('webR/webr-main.ts', './dist/webr.mjs', 'neutral', prod),
- ]
-};
-const allOutputs = outputs.browser.concat(pkg ? outputs.npm : []);
+const outputs = [
+ build('repl/App.tsx', { outfile: '../dist/repl.js', platform: 'browser', format: 'iife', target: ['es2022'], minify: prod }), // browser, script
+ build('webR/webr-main.ts', { outfile: '../dist/webr.mjs', platform: 'neutral', format: 'esm', target: ['es2022'], minify: prod }), // browser, script, type="module"
+ build('webR/webr-worker.ts', { outfile: '../dist/webr-worker.js', platform: 'neutral', format: 'iife', minify: prod }), // browser, worker
+ build('webR/webr-main.ts', { outfile: './dist/webr.cjs', platform: 'node', format: 'cjs', minify: prod }), // node, cjs
+ build('webR/webr-worker.ts', { outfile: './dist/webr-worker.js', platform: 'node', format: 'cjs', minify: prod }), // node, worker
+ build('webR/webr-main.ts', { // node, esm
+ outfile: './dist/webr.mjs',
+ platform: 'node',
+ format: 'esm',
+ banner: {
+ js: `import { createRequire } from 'module';
+import { fileURLToPath as urlESMPluginFileURLToPath } from "url";
+import { dirname as pathESMPluginDirname} from "path";
+const require = createRequire(import.meta.url);
+var __filename = urlESMPluginFileURLToPath(import.meta.url);
+var __dirname = pathESMPluginDirname(urlESMPluginFileURLToPath(import.meta.url));
+`
+ },
+ minify: prod
+ }),
+];
-allOutputs.forEach((build) => {
+outputs.forEach((build) => {
build
.then(async (context) => {
await context.rebuild();
@@ -70,7 +74,7 @@ allOutputs.forEach((build) => {
});
if (serve) {
- outputs.browser[0]
+ outputs[0]
.then(async (context) => {
await context.serve({ servedir: '../dist', port: 8001 }).then(() => {
http
@@ -101,7 +105,7 @@ if (serve) {
throw new Error('A problem occurred serving webR distribution with esbuild');
});
} else {
- allOutputs.forEach(build => {
+ outputs.forEach(build => {
build
.then(async (context) => {
await context.dispose();
diff --git a/src/package.json b/src/package.json
index 2ef99b8c..70a33e36 100644
--- a/src/package.json
+++ b/src/package.json
@@ -42,13 +42,9 @@
"exports": {
".": {
"types": "./dist/webR/webr-main.d.ts",
- "node": "./dist/webr.cjs",
+ "require": "./dist/webr.cjs",
+ "import": "./dist/webr.mjs",
"default": "./dist/webr.mjs"
- },
- "./chan/serviceworker": {
- "types": "./dist/webR/chan/serviceworker.d.ts",
- "browser": "./dist/webr-serviceworker.js",
- "default": "./dist/webr-serviceworker.mjs"
}
},
"engines": {
diff --git a/src/templates/repl.html b/src/templates/repl.html
index fe6a437c..3b743b97 100644
--- a/src/templates/repl.html
+++ b/src/templates/repl.html
@@ -34,7 +34,7 @@
-
+