@vscode/esm-url-webpack-plugin 1.0.1-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -0
- package/dist/cjs/index.d.ts +22 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +195 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/esm/index.d.ts +22 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +172 -0
- package/dist/esm/index.js.map +1 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# @vscode/esm-url-webpack-plugin
|
|
2
|
+
|
|
3
|
+
Webpack 5 plugin for handling `?esm` URL imports.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @vscode/esm-url-webpack-plugin --save-dev
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
// webpack.config.js
|
|
15
|
+
const { EsmUrlPlugin } = require('@vscode/esm-url-webpack-plugin');
|
|
16
|
+
|
|
17
|
+
module.exports = {
|
|
18
|
+
plugins: [new EsmUrlPlugin()],
|
|
19
|
+
};
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## How it works
|
|
23
|
+
|
|
24
|
+
The plugin detects `new URL('./path?esm', import.meta.url)` patterns and:
|
|
25
|
+
|
|
26
|
+
1. Creates a separate entry point for the referenced file
|
|
27
|
+
2. Bundles it with all its dependencies
|
|
28
|
+
3. Replaces the URL with the output filename
|
|
29
|
+
|
|
30
|
+
## Features
|
|
31
|
+
|
|
32
|
+
- Works with TypeScript (via ts-loader)
|
|
33
|
+
- Integrates with HtmlWebpackPlugin (excludes worker scripts from HTML)
|
|
34
|
+
- Handles multiple workers with the same filename in different directories
|
|
35
|
+
|
|
36
|
+
## Options
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
interface EsmUrlPluginOptions {
|
|
40
|
+
/**
|
|
41
|
+
* When true, strips the ?esm query parameter from output URLs.
|
|
42
|
+
* When false (default), preserves ?esm for re-bundling scenarios.
|
|
43
|
+
*/
|
|
44
|
+
stripEsmQuery?: boolean;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Custom function to generate output file names for worker/module files.
|
|
48
|
+
* Receives the file path and suggested name, should return the desired name (without extension).
|
|
49
|
+
*/
|
|
50
|
+
getOutputFileName?: (info: { filePath: string; suggestedName: string }) => string;
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Example with options
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
new EsmUrlPlugin({
|
|
58
|
+
stripEsmQuery: true,
|
|
59
|
+
getOutputFileName: ({ suggestedName }) => `worker-${suggestedName}`,
|
|
60
|
+
})
|
|
61
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Compiler } from 'webpack';
|
|
2
|
+
import { type OutputFileNameInfo } from '@vscode/esm-url-plugin-common';
|
|
3
|
+
export type { OutputFileNameInfo };
|
|
4
|
+
export interface EsmUrlPluginOptions {
|
|
5
|
+
/**
|
|
6
|
+
* When true, strips the ?esm query parameter from output URLs.
|
|
7
|
+
* When false (default), preserves ?esm for re-bundling scenarios.
|
|
8
|
+
*/
|
|
9
|
+
stripEsmQuery?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Custom function to generate output file names for worker/module files.
|
|
12
|
+
* Receives the file path and suggested name, should return the desired name (without extension).
|
|
13
|
+
*/
|
|
14
|
+
getOutputFileName?: (info: OutputFileNameInfo) => string;
|
|
15
|
+
}
|
|
16
|
+
export declare class EsmUrlPlugin {
|
|
17
|
+
private options;
|
|
18
|
+
constructor(options?: EsmUrlPluginOptions);
|
|
19
|
+
apply(compiler: Compiler): void;
|
|
20
|
+
}
|
|
21
|
+
export { EsmUrlPlugin as WebpackEsmUrlPlugin };
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,SAAS,CAAC;AACrD,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,+BAA+B,CAAC;AAEvC,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAUnC,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,MAAM,CAAC;CAC1D;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAsB;gBAEzB,OAAO,GAAE,mBAAwB;IAI7C,KAAK,CAAC,QAAQ,EAAE,QAAQ;CA0IzB;AAED,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var path = require('path');
|
|
4
|
+
var fs = require('fs');
|
|
5
|
+
|
|
6
|
+
function _interopNamespaceDefault(e) {
|
|
7
|
+
var n = Object.create(null);
|
|
8
|
+
if (e) {
|
|
9
|
+
Object.keys(e).forEach(function (k) {
|
|
10
|
+
if (k !== 'default') {
|
|
11
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
12
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return e[k]; }
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
n.default = e;
|
|
20
|
+
return Object.freeze(n);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
|
|
24
|
+
var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Strips only the 'esm' parameter from a query string, preserving other parameters.
|
|
28
|
+
* @param queryString The full query string (e.g., '?esm&foo=true' or '?foo=true&esm&bar=1')
|
|
29
|
+
* @returns The query string without the 'esm' parameter, or empty string if no params remain
|
|
30
|
+
*/
|
|
31
|
+
function stripEsmFromQuery(queryString) {
|
|
32
|
+
if (!queryString || queryString === '?esm')
|
|
33
|
+
return '';
|
|
34
|
+
const params = new URLSearchParams(queryString.startsWith('?') ? queryString.slice(1) : queryString);
|
|
35
|
+
params.delete('esm');
|
|
36
|
+
const result = params.toString();
|
|
37
|
+
return result ? '?' + result : '';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Generates a bundle entry name from a file path relative to a context directory.
|
|
42
|
+
*
|
|
43
|
+
* @param absolutePath - Absolute path to the worker/module file
|
|
44
|
+
* @param contextDir - Context directory to compute relative path from
|
|
45
|
+
* @returns A sanitized entry name suitable for use as a bundle filename
|
|
46
|
+
*/
|
|
47
|
+
function generateEntryName(absolutePath, contextDir) {
|
|
48
|
+
let relativePath = path__namespace.relative(contextDir, absolutePath);
|
|
49
|
+
// Handle cross-drive paths on Windows: path.relative() returns absolute path
|
|
50
|
+
// when paths are on different drives (e.g., C: vs D:)
|
|
51
|
+
if (path__namespace.isAbsolute(relativePath)) {
|
|
52
|
+
// Strip drive letter (e.g., "D:" or "D:\") on Windows
|
|
53
|
+
relativePath = relativePath.replace(/^[a-zA-Z]:[\\\/]?/, '');
|
|
54
|
+
}
|
|
55
|
+
return relativePath
|
|
56
|
+
.replace(/\.[^/.]+$/, '') // Remove extension
|
|
57
|
+
.replace(/\\/g, '/') // Normalize Windows slashes
|
|
58
|
+
.replace(/^(\.\.\/)+/g, '') // Remove leading ../ segments
|
|
59
|
+
.replace(/^\.\//, '') // Remove leading ./
|
|
60
|
+
.replace(/\//g, '-') // Replace slashes with dashes
|
|
61
|
+
.replace(/^\.+/, ''); // Remove any remaining leading dots
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const ESM_QUERY = '?esm';
|
|
65
|
+
|
|
66
|
+
// Try to import HtmlWebpackPlugin types if available, but don't fail if not
|
|
67
|
+
let HtmlWebpackPlugin;
|
|
68
|
+
try {
|
|
69
|
+
HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// HtmlWebpackPlugin not installed
|
|
73
|
+
}
|
|
74
|
+
class EsmUrlPlugin {
|
|
75
|
+
constructor(options = {}) {
|
|
76
|
+
this.options = options;
|
|
77
|
+
}
|
|
78
|
+
apply(compiler) {
|
|
79
|
+
const { stripEsmQuery = false, getOutputFileName } = this.options;
|
|
80
|
+
const { webpack } = compiler;
|
|
81
|
+
const EntryPlugin = webpack.EntryPlugin;
|
|
82
|
+
const ConstDependency = webpack.dependencies.ConstDependency;
|
|
83
|
+
// Detect if webpack is configured to output ES modules
|
|
84
|
+
const isOutputModule = compiler.options.experiments?.outputModule === true
|
|
85
|
+
|| compiler.options.output?.module === true;
|
|
86
|
+
compiler.hooks.compilation.tap('EsmUrlPlugin', (compilation, { normalModuleFactory }) => {
|
|
87
|
+
const entriesToAdd = new Map();
|
|
88
|
+
const addedEntryNames = new Set();
|
|
89
|
+
const handler = (parser) => {
|
|
90
|
+
parser.hooks.new.for('URL').tap('EsmUrlPlugin', (expression) => {
|
|
91
|
+
if (expression.arguments.length !== 2)
|
|
92
|
+
return;
|
|
93
|
+
const arg1 = expression.arguments[0];
|
|
94
|
+
const arg2 = expression.arguments[1];
|
|
95
|
+
// Check if second argument is import.meta.url
|
|
96
|
+
if (arg2.type !== 'MemberExpression' ||
|
|
97
|
+
arg2.object.type !== 'MetaProperty' ||
|
|
98
|
+
arg2.property.name !== 'url') {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
// Check if first argument is a string literal with ?esm
|
|
102
|
+
if (arg1.type !== 'Literal' || typeof arg1.value !== 'string')
|
|
103
|
+
return;
|
|
104
|
+
if (!arg1.value.includes(ESM_QUERY))
|
|
105
|
+
return;
|
|
106
|
+
const [workerPath, ...queryParts] = arg1.value.split('?');
|
|
107
|
+
const originalQuery = queryParts.length > 0 ? '?' + queryParts.join('?') : '';
|
|
108
|
+
const context = parser.state.module.context;
|
|
109
|
+
if (!context)
|
|
110
|
+
return;
|
|
111
|
+
const absolutePath = path__namespace.resolve(context, workerPath);
|
|
112
|
+
// Check that the file exists
|
|
113
|
+
if (!fs__namespace.existsSync(absolutePath)) {
|
|
114
|
+
const WebpackError = webpack.WebpackError;
|
|
115
|
+
const error = new WebpackError(`File not found: '${workerPath}' resolved to '${absolutePath}'. Check that the path in new URL('${arg1.value}', import.meta.url) points to an existing file.`);
|
|
116
|
+
error.name = 'EsmUrlPluginError';
|
|
117
|
+
error.module = parser.state.module;
|
|
118
|
+
error.loc = expression.loc;
|
|
119
|
+
compilation.errors.push(error);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
let entryName = generateEntryName(absolutePath, compiler.context);
|
|
123
|
+
// Apply custom output file name if provided
|
|
124
|
+
if (getOutputFileName) {
|
|
125
|
+
entryName = getOutputFileName({ filePath: absolutePath, suggestedName: entryName });
|
|
126
|
+
}
|
|
127
|
+
if (!entriesToAdd.has(absolutePath)) {
|
|
128
|
+
entriesToAdd.set(absolutePath, entryName);
|
|
129
|
+
addedEntryNames.add(entryName);
|
|
130
|
+
}
|
|
131
|
+
// Replace the entire new URL(...) expression
|
|
132
|
+
// Use import.meta.url for ESM output, otherwise use self.location.href for compatibility
|
|
133
|
+
// Note: The non-ESM version assumes worker files are served from the same base path as the HTML
|
|
134
|
+
const suffix = stripEsmQuery ? stripEsmFromQuery(originalQuery) : originalQuery;
|
|
135
|
+
const replacement = isOutputModule
|
|
136
|
+
? `new URL('./${entryName}.js${suffix}', import.meta.url)`
|
|
137
|
+
: `new URL('./${entryName}.js${suffix}', self.location.href)`;
|
|
138
|
+
const dep = new ConstDependency(replacement, expression.range);
|
|
139
|
+
dep.loc = expression.loc;
|
|
140
|
+
parser.state.module.addDependency(dep);
|
|
141
|
+
// Return true to prevent Webpack's default handling of new URL(...)
|
|
142
|
+
return true;
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
// Tap into all JS parser types
|
|
146
|
+
normalModuleFactory.hooks.parser.for('javascript/auto').tap('EsmUrlPlugin', handler);
|
|
147
|
+
normalModuleFactory.hooks.parser.for('javascript/dynamic').tap('EsmUrlPlugin', handler);
|
|
148
|
+
normalModuleFactory.hooks.parser.for('javascript/esm').tap('EsmUrlPlugin', handler);
|
|
149
|
+
// Add entries after modules are built
|
|
150
|
+
compilation.hooks.finishModules.tapAsync('EsmUrlPlugin', (modules, callback) => {
|
|
151
|
+
if (entriesToAdd.size === 0)
|
|
152
|
+
return callback();
|
|
153
|
+
const promises = [];
|
|
154
|
+
for (const [absolutePath, entryName] of entriesToAdd) {
|
|
155
|
+
// Check if entry already exists to avoid duplicates/errors
|
|
156
|
+
if (compilation.entries.has(entryName)) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const dep = EntryPlugin.createDependency(absolutePath, {
|
|
160
|
+
name: entryName
|
|
161
|
+
});
|
|
162
|
+
promises.push(new Promise((resolve, reject) => {
|
|
163
|
+
compilation.addEntry(compiler.context, dep, { name: entryName }, (err) => {
|
|
164
|
+
if (err)
|
|
165
|
+
reject(err);
|
|
166
|
+
else
|
|
167
|
+
resolve();
|
|
168
|
+
});
|
|
169
|
+
}));
|
|
170
|
+
}
|
|
171
|
+
// Clear processed entries
|
|
172
|
+
entriesToAdd.clear();
|
|
173
|
+
Promise.all(promises).then(() => callback(), (err) => callback(err));
|
|
174
|
+
});
|
|
175
|
+
// Filter out worker entries from HtmlWebpackPlugin
|
|
176
|
+
if (HtmlWebpackPlugin && HtmlWebpackPlugin.getHooks) {
|
|
177
|
+
HtmlWebpackPlugin.getHooks(compilation).beforeAssetTagGeneration.tapAsync('EsmUrlPlugin', (data, cb) => {
|
|
178
|
+
const workerFiles = new Set();
|
|
179
|
+
for (const name of addedEntryNames) {
|
|
180
|
+
const entrypoint = compilation.entrypoints.get(name);
|
|
181
|
+
if (entrypoint) {
|
|
182
|
+
entrypoint.getFiles().forEach(file => workerFiles.add(file));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
data.assets.js = data.assets.js.filter((asset) => !workerFiles.has(asset));
|
|
186
|
+
cb(null, data);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
exports.EsmUrlPlugin = EsmUrlPlugin;
|
|
194
|
+
exports.WebpackEsmUrlPlugin = EsmUrlPlugin;
|
|
195
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../common/dist/esm/index.js","../../../src/index.ts"],"sourcesContent":["import * as path from 'path';\n\n/**\n * Strips only the 'esm' parameter from a query string, preserving other parameters.\n * @param queryString The full query string (e.g., '?esm&foo=true' or '?foo=true&esm&bar=1')\n * @returns The query string without the 'esm' parameter, or empty string if no params remain\n */\nfunction stripEsmFromQuery(queryString) {\n if (!queryString || queryString === '?esm')\n return '';\n const params = new URLSearchParams(queryString.startsWith('?') ? queryString.slice(1) : queryString);\n params.delete('esm');\n const result = params.toString();\n return result ? '?' + result : '';\n}\n\n/**\n * Generates a bundle entry name from a file path relative to a context directory.\n *\n * @param absolutePath - Absolute path to the worker/module file\n * @param contextDir - Context directory to compute relative path from\n * @returns A sanitized entry name suitable for use as a bundle filename\n */\nfunction generateEntryName(absolutePath, contextDir) {\n let relativePath = path.relative(contextDir, absolutePath);\n // Handle cross-drive paths on Windows: path.relative() returns absolute path\n // when paths are on different drives (e.g., C: vs D:)\n if (path.isAbsolute(relativePath)) {\n // Strip drive letter (e.g., \"D:\" or \"D:\\\") on Windows\n relativePath = relativePath.replace(/^[a-zA-Z]:[\\\\\\/]?/, '');\n }\n return relativePath\n .replace(/\\.[^/.]+$/, '') // Remove extension\n .replace(/\\\\/g, '/') // Normalize Windows slashes\n .replace(/^(\\.\\.\\/)+/g, '') // Remove leading ../ segments\n .replace(/^\\.\\//, '') // Remove leading ./\n .replace(/\\//g, '-') // Replace slashes with dashes\n .replace(/^\\.+/, ''); // Remove any remaining leading dots\n}\n\nconst ESM_QUERY = '?esm';\n/**\n * Finds `new URL('...?esm...', import.meta.url)` patterns using regex.\n * May have false positives in comments or strings, but this is rare in practice.\n */\nfunction findMatches(code) {\n const urlPattern = /new\\s+URL\\s*\\(\\s*(['\"`])([^'\"`]+\\?esm[^'\"`]*)\\1\\s*,\\s*import\\.meta\\.url\\s*\\)/g;\n const matches = [];\n let match;\n while ((match = urlPattern.exec(code)) !== null) {\n const urlString = match[2];\n if (urlString.includes(ESM_QUERY)) {\n matches.push({\n urlString,\n start: match.index,\n end: match.index + match[0].length,\n });\n }\n }\n return matches;\n}\n\nexport { ESM_QUERY, findMatches, generateEntryName, stripEsmFromQuery };\n//# sourceMappingURL=index.js.map\n",null],"names":["path","fs"],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Compiler } from 'webpack';
|
|
2
|
+
import { type OutputFileNameInfo } from '@vscode/esm-url-plugin-common';
|
|
3
|
+
export type { OutputFileNameInfo };
|
|
4
|
+
export interface EsmUrlPluginOptions {
|
|
5
|
+
/**
|
|
6
|
+
* When true, strips the ?esm query parameter from output URLs.
|
|
7
|
+
* When false (default), preserves ?esm for re-bundling scenarios.
|
|
8
|
+
*/
|
|
9
|
+
stripEsmQuery?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Custom function to generate output file names for worker/module files.
|
|
12
|
+
* Receives the file path and suggested name, should return the desired name (without extension).
|
|
13
|
+
*/
|
|
14
|
+
getOutputFileName?: (info: OutputFileNameInfo) => string;
|
|
15
|
+
}
|
|
16
|
+
export declare class EsmUrlPlugin {
|
|
17
|
+
private options;
|
|
18
|
+
constructor(options?: EsmUrlPluginOptions);
|
|
19
|
+
apply(compiler: Compiler): void;
|
|
20
|
+
}
|
|
21
|
+
export { EsmUrlPlugin as WebpackEsmUrlPlugin };
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,SAAS,CAAC;AACrD,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,+BAA+B,CAAC;AAEvC,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAUnC,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,MAAM,CAAC;CAC1D;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAsB;gBAEzB,OAAO,GAAE,mBAAwB;IAI7C,KAAK,CAAC,QAAQ,EAAE,QAAQ;CA0IzB;AAED,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Strips only the 'esm' parameter from a query string, preserving other parameters.
|
|
6
|
+
* @param queryString The full query string (e.g., '?esm&foo=true' or '?foo=true&esm&bar=1')
|
|
7
|
+
* @returns The query string without the 'esm' parameter, or empty string if no params remain
|
|
8
|
+
*/
|
|
9
|
+
function stripEsmFromQuery(queryString) {
|
|
10
|
+
if (!queryString || queryString === '?esm')
|
|
11
|
+
return '';
|
|
12
|
+
const params = new URLSearchParams(queryString.startsWith('?') ? queryString.slice(1) : queryString);
|
|
13
|
+
params.delete('esm');
|
|
14
|
+
const result = params.toString();
|
|
15
|
+
return result ? '?' + result : '';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Generates a bundle entry name from a file path relative to a context directory.
|
|
20
|
+
*
|
|
21
|
+
* @param absolutePath - Absolute path to the worker/module file
|
|
22
|
+
* @param contextDir - Context directory to compute relative path from
|
|
23
|
+
* @returns A sanitized entry name suitable for use as a bundle filename
|
|
24
|
+
*/
|
|
25
|
+
function generateEntryName(absolutePath, contextDir) {
|
|
26
|
+
let relativePath = path.relative(contextDir, absolutePath);
|
|
27
|
+
// Handle cross-drive paths on Windows: path.relative() returns absolute path
|
|
28
|
+
// when paths are on different drives (e.g., C: vs D:)
|
|
29
|
+
if (path.isAbsolute(relativePath)) {
|
|
30
|
+
// Strip drive letter (e.g., "D:" or "D:\") on Windows
|
|
31
|
+
relativePath = relativePath.replace(/^[a-zA-Z]:[\\\/]?/, '');
|
|
32
|
+
}
|
|
33
|
+
return relativePath
|
|
34
|
+
.replace(/\.[^/.]+$/, '') // Remove extension
|
|
35
|
+
.replace(/\\/g, '/') // Normalize Windows slashes
|
|
36
|
+
.replace(/^(\.\.\/)+/g, '') // Remove leading ../ segments
|
|
37
|
+
.replace(/^\.\//, '') // Remove leading ./
|
|
38
|
+
.replace(/\//g, '-') // Replace slashes with dashes
|
|
39
|
+
.replace(/^\.+/, ''); // Remove any remaining leading dots
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const ESM_QUERY = '?esm';
|
|
43
|
+
|
|
44
|
+
// Try to import HtmlWebpackPlugin types if available, but don't fail if not
|
|
45
|
+
let HtmlWebpackPlugin;
|
|
46
|
+
try {
|
|
47
|
+
HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// HtmlWebpackPlugin not installed
|
|
51
|
+
}
|
|
52
|
+
class EsmUrlPlugin {
|
|
53
|
+
constructor(options = {}) {
|
|
54
|
+
this.options = options;
|
|
55
|
+
}
|
|
56
|
+
apply(compiler) {
|
|
57
|
+
const { stripEsmQuery = false, getOutputFileName } = this.options;
|
|
58
|
+
const { webpack } = compiler;
|
|
59
|
+
const EntryPlugin = webpack.EntryPlugin;
|
|
60
|
+
const ConstDependency = webpack.dependencies.ConstDependency;
|
|
61
|
+
// Detect if webpack is configured to output ES modules
|
|
62
|
+
const isOutputModule = compiler.options.experiments?.outputModule === true
|
|
63
|
+
|| compiler.options.output?.module === true;
|
|
64
|
+
compiler.hooks.compilation.tap('EsmUrlPlugin', (compilation, { normalModuleFactory }) => {
|
|
65
|
+
const entriesToAdd = new Map();
|
|
66
|
+
const addedEntryNames = new Set();
|
|
67
|
+
const handler = (parser) => {
|
|
68
|
+
parser.hooks.new.for('URL').tap('EsmUrlPlugin', (expression) => {
|
|
69
|
+
if (expression.arguments.length !== 2)
|
|
70
|
+
return;
|
|
71
|
+
const arg1 = expression.arguments[0];
|
|
72
|
+
const arg2 = expression.arguments[1];
|
|
73
|
+
// Check if second argument is import.meta.url
|
|
74
|
+
if (arg2.type !== 'MemberExpression' ||
|
|
75
|
+
arg2.object.type !== 'MetaProperty' ||
|
|
76
|
+
arg2.property.name !== 'url') {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// Check if first argument is a string literal with ?esm
|
|
80
|
+
if (arg1.type !== 'Literal' || typeof arg1.value !== 'string')
|
|
81
|
+
return;
|
|
82
|
+
if (!arg1.value.includes(ESM_QUERY))
|
|
83
|
+
return;
|
|
84
|
+
const [workerPath, ...queryParts] = arg1.value.split('?');
|
|
85
|
+
const originalQuery = queryParts.length > 0 ? '?' + queryParts.join('?') : '';
|
|
86
|
+
const context = parser.state.module.context;
|
|
87
|
+
if (!context)
|
|
88
|
+
return;
|
|
89
|
+
const absolutePath = path.resolve(context, workerPath);
|
|
90
|
+
// Check that the file exists
|
|
91
|
+
if (!fs.existsSync(absolutePath)) {
|
|
92
|
+
const WebpackError = webpack.WebpackError;
|
|
93
|
+
const error = new WebpackError(`File not found: '${workerPath}' resolved to '${absolutePath}'. Check that the path in new URL('${arg1.value}', import.meta.url) points to an existing file.`);
|
|
94
|
+
error.name = 'EsmUrlPluginError';
|
|
95
|
+
error.module = parser.state.module;
|
|
96
|
+
error.loc = expression.loc;
|
|
97
|
+
compilation.errors.push(error);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
let entryName = generateEntryName(absolutePath, compiler.context);
|
|
101
|
+
// Apply custom output file name if provided
|
|
102
|
+
if (getOutputFileName) {
|
|
103
|
+
entryName = getOutputFileName({ filePath: absolutePath, suggestedName: entryName });
|
|
104
|
+
}
|
|
105
|
+
if (!entriesToAdd.has(absolutePath)) {
|
|
106
|
+
entriesToAdd.set(absolutePath, entryName);
|
|
107
|
+
addedEntryNames.add(entryName);
|
|
108
|
+
}
|
|
109
|
+
// Replace the entire new URL(...) expression
|
|
110
|
+
// Use import.meta.url for ESM output, otherwise use self.location.href for compatibility
|
|
111
|
+
// Note: The non-ESM version assumes worker files are served from the same base path as the HTML
|
|
112
|
+
const suffix = stripEsmQuery ? stripEsmFromQuery(originalQuery) : originalQuery;
|
|
113
|
+
const replacement = isOutputModule
|
|
114
|
+
? `new URL('./${entryName}.js${suffix}', import.meta.url)`
|
|
115
|
+
: `new URL('./${entryName}.js${suffix}', self.location.href)`;
|
|
116
|
+
const dep = new ConstDependency(replacement, expression.range);
|
|
117
|
+
dep.loc = expression.loc;
|
|
118
|
+
parser.state.module.addDependency(dep);
|
|
119
|
+
// Return true to prevent Webpack's default handling of new URL(...)
|
|
120
|
+
return true;
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
// Tap into all JS parser types
|
|
124
|
+
normalModuleFactory.hooks.parser.for('javascript/auto').tap('EsmUrlPlugin', handler);
|
|
125
|
+
normalModuleFactory.hooks.parser.for('javascript/dynamic').tap('EsmUrlPlugin', handler);
|
|
126
|
+
normalModuleFactory.hooks.parser.for('javascript/esm').tap('EsmUrlPlugin', handler);
|
|
127
|
+
// Add entries after modules are built
|
|
128
|
+
compilation.hooks.finishModules.tapAsync('EsmUrlPlugin', (modules, callback) => {
|
|
129
|
+
if (entriesToAdd.size === 0)
|
|
130
|
+
return callback();
|
|
131
|
+
const promises = [];
|
|
132
|
+
for (const [absolutePath, entryName] of entriesToAdd) {
|
|
133
|
+
// Check if entry already exists to avoid duplicates/errors
|
|
134
|
+
if (compilation.entries.has(entryName)) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const dep = EntryPlugin.createDependency(absolutePath, {
|
|
138
|
+
name: entryName
|
|
139
|
+
});
|
|
140
|
+
promises.push(new Promise((resolve, reject) => {
|
|
141
|
+
compilation.addEntry(compiler.context, dep, { name: entryName }, (err) => {
|
|
142
|
+
if (err)
|
|
143
|
+
reject(err);
|
|
144
|
+
else
|
|
145
|
+
resolve();
|
|
146
|
+
});
|
|
147
|
+
}));
|
|
148
|
+
}
|
|
149
|
+
// Clear processed entries
|
|
150
|
+
entriesToAdd.clear();
|
|
151
|
+
Promise.all(promises).then(() => callback(), (err) => callback(err));
|
|
152
|
+
});
|
|
153
|
+
// Filter out worker entries from HtmlWebpackPlugin
|
|
154
|
+
if (HtmlWebpackPlugin && HtmlWebpackPlugin.getHooks) {
|
|
155
|
+
HtmlWebpackPlugin.getHooks(compilation).beforeAssetTagGeneration.tapAsync('EsmUrlPlugin', (data, cb) => {
|
|
156
|
+
const workerFiles = new Set();
|
|
157
|
+
for (const name of addedEntryNames) {
|
|
158
|
+
const entrypoint = compilation.entrypoints.get(name);
|
|
159
|
+
if (entrypoint) {
|
|
160
|
+
entrypoint.getFiles().forEach(file => workerFiles.add(file));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
data.assets.js = data.assets.js.filter((asset) => !workerFiles.has(asset));
|
|
164
|
+
cb(null, data);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export { EsmUrlPlugin, EsmUrlPlugin as WebpackEsmUrlPlugin };
|
|
172
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../common/dist/esm/index.js","../../../src/index.ts"],"sourcesContent":["import * as path from 'path';\n\n/**\n * Strips only the 'esm' parameter from a query string, preserving other parameters.\n * @param queryString The full query string (e.g., '?esm&foo=true' or '?foo=true&esm&bar=1')\n * @returns The query string without the 'esm' parameter, or empty string if no params remain\n */\nfunction stripEsmFromQuery(queryString) {\n if (!queryString || queryString === '?esm')\n return '';\n const params = new URLSearchParams(queryString.startsWith('?') ? queryString.slice(1) : queryString);\n params.delete('esm');\n const result = params.toString();\n return result ? '?' + result : '';\n}\n\n/**\n * Generates a bundle entry name from a file path relative to a context directory.\n *\n * @param absolutePath - Absolute path to the worker/module file\n * @param contextDir - Context directory to compute relative path from\n * @returns A sanitized entry name suitable for use as a bundle filename\n */\nfunction generateEntryName(absolutePath, contextDir) {\n let relativePath = path.relative(contextDir, absolutePath);\n // Handle cross-drive paths on Windows: path.relative() returns absolute path\n // when paths are on different drives (e.g., C: vs D:)\n if (path.isAbsolute(relativePath)) {\n // Strip drive letter (e.g., \"D:\" or \"D:\\\") on Windows\n relativePath = relativePath.replace(/^[a-zA-Z]:[\\\\\\/]?/, '');\n }\n return relativePath\n .replace(/\\.[^/.]+$/, '') // Remove extension\n .replace(/\\\\/g, '/') // Normalize Windows slashes\n .replace(/^(\\.\\.\\/)+/g, '') // Remove leading ../ segments\n .replace(/^\\.\\//, '') // Remove leading ./\n .replace(/\\//g, '-') // Replace slashes with dashes\n .replace(/^\\.+/, ''); // Remove any remaining leading dots\n}\n\nconst ESM_QUERY = '?esm';\n/**\n * Finds `new URL('...?esm...', import.meta.url)` patterns using regex.\n * May have false positives in comments or strings, but this is rare in practice.\n */\nfunction findMatches(code) {\n const urlPattern = /new\\s+URL\\s*\\(\\s*(['\"`])([^'\"`]+\\?esm[^'\"`]*)\\1\\s*,\\s*import\\.meta\\.url\\s*\\)/g;\n const matches = [];\n let match;\n while ((match = urlPattern.exec(code)) !== null) {\n const urlString = match[2];\n if (urlString.includes(ESM_QUERY)) {\n matches.push({\n urlString,\n start: match.index,\n end: match.index + match[0].length,\n });\n }\n }\n return matches;\n}\n\nexport { ESM_QUERY, findMatches, generateEntryName, stripEsmFromQuery };\n//# sourceMappingURL=index.js.map\n",null],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vscode/esm-url-webpack-plugin",
|
|
3
|
+
"version": "1.0.1-0",
|
|
4
|
+
"description": "Webpack 5 plugin for handling ?esm URL imports",
|
|
5
|
+
"main": "./dist/cjs/index.js",
|
|
6
|
+
"module": "./dist/esm/index.js",
|
|
7
|
+
"types": "./dist/cjs/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/esm/index.d.ts",
|
|
12
|
+
"default": "./dist/esm/index.js"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/cjs/index.d.ts",
|
|
16
|
+
"default": "./dist/cjs/index.js"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "rollup -c rollup.config.mjs",
|
|
25
|
+
"clean": "rimraf dist"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@vscode/esm-url-plugin-common": "*",
|
|
29
|
+
"rollup": "^4.0.0"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"webpack": "^5.0.0"
|
|
33
|
+
},
|
|
34
|
+
"license": "MIT"
|
|
35
|
+
}
|