@rollup-extras/plugin-script-loader 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Konstantin Shutkin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,313 @@
1
+ # Plugin Script Loader
2
+
3
+ Rollup plugin to mimic Webpack's `script-loader` inline behavior. Inlines raw scripts into the bundle in import order, or emits them as a separate asset file for non-module, non-strict mode execution.
4
+
5
+ [Changelog](./CHANGELOG.md)
6
+
7
+ ## Installation
8
+
9
+ Using npm:
10
+
11
+ ```
12
+ npm install --save-dev @rollup-extras/plugin-script-loader
13
+ ```
14
+
15
+ ## The Problem
16
+
17
+ In legacy codebases using libraries like d3 or AngularJS, you need to:
18
+
19
+ - Load scripts in a **stable, deterministic order** (e.g., d3 before d3 plugins, AngularJS before Angular modules)
20
+ - **Concatenate** everything into a single bundle
21
+ - Pass all code through the **optimization layer** (terser) — not hidden inside `eval()` strings
22
+ - Support **legacy libraries** that aren't proper ES modules
23
+ - Optionally, run legacy code in **sloppy mode** (non-strict) outside the main ES module bundle
24
+
25
+ In Webpack, this is solved with `script-loader`:
26
+
27
+ ```javascript
28
+ import "script-loader!d3";
29
+ import "script-loader!d3-plugin1";
30
+ import "script-loader!angular";
31
+ import "script-loader!angular-route";
32
+ ```
33
+
34
+ This plugin brings the same pattern to Rollup.
35
+
36
+ ## How It Works
37
+
38
+ The plugin intercepts imports that start with a configurable prefix (`script!` by default), resolves the underlying module, and processes it based on the `emit` option:
39
+
40
+ - **`emit: 'inline'`** (default) — Inlines the raw source code directly into the bundle at the import site
41
+ - **`emit: 'asset'`** — Collects all scripts and emits them as a separate concatenated asset file
42
+
43
+ Because the code is handled as real JavaScript (not wrapped in `eval()` or `new Function()`), it:
44
+
45
+ - Preserves **import order** — scripts appear exactly as imported
46
+ - Is fully visible to **terser** and other optimization plugins
47
+ - Gets **concatenated** into a single output
48
+ - Is **CSP-safe** — no dynamic code evaluation
49
+
50
+ ## Example: Inline Mode (Default)
51
+
52
+ ```javascript
53
+ import scriptLoader from "@rollup-extras/plugin-script-loader";
54
+
55
+ export default {
56
+ input: "src/index.js",
57
+
58
+ output: {
59
+ format: "iife",
60
+ file: "dist/bundle.js",
61
+ },
62
+
63
+ plugins: [scriptLoader()],
64
+ };
65
+ ```
66
+
67
+ In your entry point:
68
+
69
+ ```javascript
70
+ // Legacy libraries — inlined in this exact order
71
+ import "script!d3";
72
+ import "script!d3-tip";
73
+ import "script!angular";
74
+ import "script!angular-route";
75
+ import "script!angular-sanitize";
76
+
77
+ // Your application code (regular ES module imports)
78
+ import { app } from "./app.js";
79
+
80
+ app.init();
81
+ ```
82
+
83
+ ## Example: Asset Mode (Emit Separate File)
84
+
85
+ For legacy code that must run in true sloppy (non-strict) mode, use `emit: 'asset'` to emit a separate classic script file:
86
+
87
+ ```javascript
88
+ import scriptLoader from "@rollup-extras/plugin-script-loader";
89
+
90
+ export default {
91
+ input: "src/index.js",
92
+
93
+ output: {
94
+ format: "es",
95
+ dir: "dist",
96
+ sourcemap: true,
97
+ },
98
+
99
+ plugins: [
100
+ scriptLoader({
101
+ emit: "asset",
102
+ name: "vendor.js",
103
+ sourcemap: true,
104
+ }),
105
+ ],
106
+ };
107
+ ```
108
+
109
+ This emits `vendor.js` as a separate asset file containing all concatenated scripts. Include it in your HTML before the main bundle:
110
+
111
+ ```html
112
+ <script src="vendor.js"></script>
113
+ <script src="main.js" type="module"></script>
114
+ ```
115
+
116
+ ### With Content Hashing
117
+
118
+ To let Rollup apply its `assetFileNames` pattern for content hashing:
119
+
120
+ ```javascript
121
+ scriptLoader({
122
+ emit: "asset",
123
+ name: "vendor.js",
124
+ exactFileName: false, // Use Rollup's assetFileNames pattern
125
+ });
126
+ ```
127
+
128
+ With `output.assetFileNames: 'assets/[name].[hash].[ext]'`, this outputs `assets/vendor.abc123.js`.
129
+
130
+ ### With Minification
131
+
132
+ Provide a custom `minify` function to minify the concatenated output:
133
+
134
+ ```javascript
135
+ import { minify } from "terser";
136
+
137
+ scriptLoader({
138
+ emit: "asset",
139
+ name: "vendor.js",
140
+ minify: async (code, map) => {
141
+ const result = await minify(code, {
142
+ sourceMap: map ? { content: map } : false,
143
+ });
144
+ return { code: result.code, map: result.map };
145
+ },
146
+ });
147
+ ```
148
+
149
+ Or with oxc-minify:
150
+
151
+ ```javascript
152
+ import { minify } from "oxc-minify";
153
+
154
+ scriptLoader({
155
+ emit: "asset",
156
+ minify: async (code) => {
157
+ const result = await minify("vendor.js", code);
158
+ return { code: result.code, map: result.map };
159
+ },
160
+ });
161
+ ```
162
+
163
+ ### Integration with plugin-html
164
+
165
+ Use with `@rollup-extras/plugin-html` to automatically inject the vendor bundle:
166
+
167
+ ```javascript
168
+ import scriptLoader from "@rollup-extras/plugin-script-loader";
169
+ import html from "@rollup-extras/plugin-html";
170
+ import {
171
+ simpleES5Script,
172
+ combineAssetFactories,
173
+ } from "@rollup-extras/plugin-html/asset-factories";
174
+
175
+ export default {
176
+ input: "src/main.js",
177
+ output: {
178
+ format: "es",
179
+ dir: "dist",
180
+ sourcemap: true,
181
+ assetFileNames: "assets/[name].[hash].[ext]",
182
+ },
183
+ plugins: [
184
+ scriptLoader({
185
+ emit: "asset",
186
+ name: "vendor.js",
187
+ exactFileName: false,
188
+ sourcemap: true,
189
+ }),
190
+
191
+ html({
192
+ template: "index.html",
193
+ assetsFactory: combineAssetFactories(
194
+ simpleES5Script(/vendor\..*\.js$/) // Inject vendor as classic script
195
+ ),
196
+ }),
197
+ ],
198
+ };
199
+ ```
200
+
201
+ ## Configuration
202
+
203
+ ```typescript
204
+ type ScriptLoaderPluginOptions = {
205
+ // Existing options
206
+ prefix?: string; // 'script!' by default
207
+ useStrict?: boolean; // true by default (for inline mode)
208
+ pluginName?: string; // '@rollup-extras/plugin-script-loader' by default
209
+ verbose?: boolean; // false by default
210
+
211
+ // Emit mode options
212
+ emit?: "inline" | "asset"; // 'inline' by default
213
+ name?: string; // 'vendor.js' by default
214
+ exactFileName?: boolean; // true by default
215
+ sourcemap?: boolean; // true by default when emit: 'asset'
216
+ minify?: (
217
+ code: string,
218
+ sourcemap?: SourceMap
219
+ ) => Promise<{ code: string; map?: SourceMap }>;
220
+ };
221
+ ```
222
+
223
+ ### `emit`
224
+
225
+ - **`'inline'`** (default) — Scripts are inlined into the main bundle (current behavior)
226
+ - **`'asset'`** — Scripts are concatenated and emitted as a separate asset file
227
+
228
+ ### `name`
229
+
230
+ Base name for the emitted asset file. Only used when `emit: 'asset'`.
231
+
232
+ Default: `'vendor.js'`
233
+
234
+ ### `exactFileName`
235
+
236
+ Controls how the asset filename is determined. Only used when `emit: 'asset'`.
237
+
238
+ - **`true`** (default) — Uses Rollup's `fileName` property; asset emitted with exact name (e.g., `vendor.js`)
239
+ - **`false`** — Uses Rollup's `name` property; Rollup applies `output.assetFileNames` pattern (e.g., `assets/vendor.abc123.js`)
240
+
241
+ ### `sourcemap`
242
+
243
+ Whether to generate sourcemaps for the emitted asset. Only used when `emit: 'asset'`.
244
+
245
+ Default: `true` when `emit: 'asset'`
246
+
247
+ When enabled, generates a concatenated sourcemap (`vendor.js.map`) pointing back to original source files.
248
+
249
+ ### `minify`
250
+
251
+ Optional async function to minify the concatenated code. Only used when `emit: 'asset'`.
252
+
253
+ Receives the code and optionally the sourcemap, returns minified code and optionally a new sourcemap.
254
+
255
+ ### `useStrict`
256
+
257
+ Controls whether the inlined script is parsed in strict mode or sloppy (non-strict) mode. Only applies to `emit: 'inline'` mode.
258
+
259
+ - **`true`** (default) — appends `export {}` to the loaded code, which makes Rollup's parser treat the file as an ES module (strict mode)
260
+ - **`false`** — does not append `export {}`, so the parser uses script (sloppy) mode
261
+
262
+ ```javascript
263
+ // Sloppy mode for legacy libraries that break under strict parsing
264
+ scriptLoader({ useStrict: false });
265
+ ```
266
+
267
+ > **Note:** `useStrict` only controls _parse-time_ mode. For the output to actually run in non-strict mode at runtime, you also need `output.strict: false` in your Rollup config (applies to `iife`, `cjs`, and `umd` formats). The `es` format is always strict per spec. For true sloppy mode at runtime, use `emit: 'asset'` instead.
268
+
269
+ ### `prefix`
270
+
271
+ The import prefix that triggers script loading.
272
+
273
+ Default: `'script!'`
274
+
275
+ For Webpack migration compatibility:
276
+
277
+ ```javascript
278
+ scriptLoader({ prefix: "script-loader!" });
279
+ ```
280
+
281
+ ### `verbose`
282
+
283
+ Enables detailed logging of processed scripts.
284
+
285
+ Default: `false`
286
+
287
+ ## Notes
288
+
289
+ ### Global Scope
290
+
291
+ With `format: 'iife'`, all inlined code shares the same function scope. Libraries that explicitly assign to `window` (e.g., `window.d3 = ...`, `window.angular = ...`) work correctly.
292
+
293
+ With `emit: 'asset'`, the emitted file runs as a classic script in true global scope — ideal for legacy libraries.
294
+
295
+ ### Works With node-resolve
296
+
297
+ The plugin delegates module resolution to other plugins via Rollup's `this.resolve()`. This means `script!d3` will be resolved by `@rollup/plugin-node-resolve` (if present) just like a regular import — picking up the file from `node_modules`.
298
+
299
+ ### Works With terser
300
+
301
+ Since the code is handled as real JavaScript, `@rollup/plugin-terser` can process inline mode output. For asset mode, use the `minify` option to apply minification to the concatenated output.
302
+
303
+ ### Watch Mode
304
+
305
+ The plugin properly clears its state between builds, fully supporting Rollup's watch mode.
306
+
307
+ ## Prior Art
308
+
309
+ - [script-loader](https://github.com/webpack-contrib/script-loader) (Webpack, deprecated)
310
+
311
+ # License
312
+
313
+ [MIT](https://github.com/kshutkin/rollup-extras/blob/main/LICENSE)
package/index.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ declare module '@rollup-extras/plugin-script-loader' {
2
+ import type { Plugin, SourceMap } from 'rollup';
3
+ export default function _default(options?: ScriptLoaderPluginOptions): Plugin;
4
+ export type ScriptLoaderPluginOptions = {
5
+ prefix?: string;
6
+ useStrict?: boolean;
7
+ pluginName?: string;
8
+ verbose?: boolean;
9
+ emit?: "inline" | "asset";
10
+ name?: string;
11
+ exactFileName?: boolean;
12
+ sourcemap?: boolean;
13
+ minify?: (code: string, sourcemap?: SourceMap) => Promise<{
14
+ code: string;
15
+ map?: SourceMap;
16
+ }>;
17
+ };
18
+ export type ScriptEntry = {
19
+ filePath: string;
20
+ code: string;
21
+ originalMap?: SourceMap;
22
+ };
23
+
24
+ export {};
25
+ }
26
+
27
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": 3,
3
+ "file": "index.d.ts",
4
+ "names": [],
5
+ "sources": [],
6
+ "sourcesContent": [],
7
+ "mappings": "",
8
+ "ignoreList": []
9
+ }
package/index.js ADDED
@@ -0,0 +1,267 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { basename } from 'node:path';
3
+
4
+ import MagicString, { Bundle } from 'magic-string';
5
+
6
+ import { LogLevel } from '@niceties/logger';
7
+ import logger from '@rollup-extras/utils/logger';
8
+ import { getOptionsObject } from '@rollup-extras/utils/options';
9
+ import statistics from '@rollup-extras/utils/statistics';
10
+
11
+ const scriptPrefix = '\0script-loader:';
12
+
13
+ const factories = { logger };
14
+
15
+ export default function (options = {}) {
16
+ const normalizedOptions = getOptionsObject(
17
+ options,
18
+ {
19
+ pluginName: '@rollup-extras/plugin-script-loader',
20
+ prefix: 'script!',
21
+ useStrict: (true),
22
+ verbose: (false),
23
+ emit: ('inline'),
24
+ name: 'vendor.js',
25
+ exactFileName: (true),
26
+ sourcemap: (undefined),
27
+ minify: (
28
+ undefined
29
+ ),
30
+ },
31
+ factories
32
+ );
33
+
34
+ const { pluginName, prefix, useStrict, verbose, logger, emit, name, exactFileName, minify } = normalizedOptions;
35
+
36
+ const sourcemap = normalizedOptions.sourcemap ?? emit === 'asset';
37
+
38
+ const statisticsCollector = statistics(
39
+ false,
40
+ ( result) => `inlined ${typeof result === 'number' ? `${result} scripts` : result.join(', ')}`
41
+ );
42
+
43
+ const scripts = new Map();
44
+
45
+ const importOrder = [];
46
+
47
+ async function tryReadSourcemap(filePath, code) {
48
+
49
+ const inlineMatch = code.match(
50
+ /\/\/[#@]\s*sourceMappingURL=data:application\/json;(?:charset=utf-8;)?base64,([A-Za-z0-9+/=]+)\s*$/
51
+ );
52
+ if (inlineMatch) {
53
+ try {
54
+ const decoded = Buffer.from(inlineMatch[1], 'base64').toString('utf8');
55
+ return JSON.parse(decoded);
56
+ } catch {
57
+
58
+ }
59
+ }
60
+
61
+ const externalMatch = code.match(/\/\/[#@]\s*sourceMappingURL=(.+?)\s*$/);
62
+ if (externalMatch && !externalMatch[1].startsWith('data:')) {
63
+ try {
64
+ const mapPath = `${filePath}.map`;
65
+ const mapContent = await readFile(mapPath, 'utf8');
66
+ return JSON.parse(mapContent);
67
+ } catch {
68
+
69
+ }
70
+ }
71
+
72
+ return undefined;
73
+ }
74
+
75
+ function stripSourcemapComment(code) {
76
+ return code.replace(/\n?\/\/[#@]\s*sourceMappingURL=.+?\s*$/, '');
77
+ }
78
+
79
+ return ({
80
+ name: pluginName,
81
+
82
+ async resolveId(source, importer, resolveOptions) {
83
+ if (!source.startsWith(prefix)) {
84
+ return null;
85
+ }
86
+
87
+ const bareSpecifier = source.slice(prefix.length);
88
+
89
+ const resolved = await this.resolve(bareSpecifier, importer, { ...resolveOptions, skipSelf: true });
90
+
91
+ if (!resolved) {
92
+ this.warn(`Could not resolve "${bareSpecifier}" (from "${source}")`);
93
+ return null;
94
+ }
95
+
96
+ let resolvedPath = resolved.id;
97
+ if (resolvedPath.startsWith('\0')) {
98
+ resolvedPath = resolvedPath.slice(1);
99
+ }
100
+ const queryIndex = resolvedPath.indexOf('?');
101
+ if (queryIndex !== -1) {
102
+ resolvedPath = resolvedPath.slice(0, queryIndex);
103
+ }
104
+
105
+ const virtualId = scriptPrefix + resolvedPath;
106
+
107
+ return {
108
+ id: virtualId,
109
+ moduleSideEffects: true,
110
+ };
111
+ },
112
+
113
+ moduleParsed(moduleInfo) {
114
+ if (emit !== 'asset') {
115
+ return;
116
+ }
117
+
118
+ for (const importedId of moduleInfo.importedIds) {
119
+ if (importedId.startsWith(scriptPrefix) && !importOrder.includes(importedId)) {
120
+ importOrder.push(importedId);
121
+ }
122
+ }
123
+ },
124
+
125
+ async load(id) {
126
+ if (!id.startsWith(scriptPrefix)) {
127
+ return null;
128
+ }
129
+
130
+ const realPath = id.slice(scriptPrefix.length);
131
+
132
+ this.addWatchFile(realPath);
133
+
134
+ logger.start('inlining scripts', verbose ? LogLevel.info : LogLevel.verbose);
135
+
136
+ const code = (await readFile(realPath)).toString();
137
+
138
+ const shortName = (realPath.split('/').pop());
139
+ if (verbose) {
140
+ logger(`\t${realPath}`, LogLevel.info);
141
+ }
142
+ statisticsCollector(shortName);
143
+
144
+ logger.finish( (statisticsCollector()));
145
+
146
+ if (emit === 'asset') {
147
+
148
+ const originalMap = sourcemap ? await tryReadSourcemap(realPath, code) : undefined;
149
+ const cleanCode = stripSourcemapComment(code);
150
+
151
+ scripts.set(id, {
152
+ filePath: realPath,
153
+ code: cleanCode,
154
+ originalMap,
155
+ });
156
+
157
+ return {
158
+ code: `/* [script-loader] externalized: ${realPath} */\n`,
159
+ map: null,
160
+ moduleSideEffects: true,
161
+ };
162
+ }
163
+
164
+ return {
165
+ code: useStrict ? `${code}\nexport {}\n` : code,
166
+ map: null,
167
+ moduleSideEffects: true,
168
+ };
169
+ },
170
+
171
+ async generateBundle(_outputOptions, bundle) {
172
+ if (emit !== 'asset' || scripts.size === 0) {
173
+ return;
174
+ }
175
+
176
+ const sortedEntries = Array.from(scripts.entries())
177
+ .sort(([idA], [idB]) => {
178
+ const orderA = importOrder.indexOf(idA);
179
+ const orderB = importOrder.indexOf(idB);
180
+
181
+ if (orderA !== -1 && orderB !== -1) {
182
+ return orderA - orderB;
183
+ }
184
+ if (orderA !== -1) return -1;
185
+ if (orderB !== -1) return 1;
186
+ return 0;
187
+ })
188
+ .map(([, entry]) => entry);
189
+
190
+ const magicBundle = new Bundle({ separator: '\n' });
191
+
192
+ for (const entry of sortedEntries) {
193
+ const ms = new MagicString(entry.code, {
194
+ filename: entry.filePath,
195
+ });
196
+
197
+ magicBundle.addSource({
198
+ filename: entry.filePath,
199
+ content: ms,
200
+ });
201
+ }
202
+
203
+ let concatenatedCode = magicBundle.toString();
204
+
205
+ let generatedMap;
206
+
207
+ if (sourcemap) {
208
+ generatedMap = (
209
+ magicBundle.generateMap({
210
+ file: name,
211
+ source: name,
212
+ includeContent: true,
213
+ hires: true,
214
+ })
215
+ );
216
+ }
217
+
218
+ if (minify) {
219
+ try {
220
+ const minified = await minify(concatenatedCode, generatedMap);
221
+ concatenatedCode = minified.code;
222
+ if (minified.map) {
223
+ generatedMap = minified.map;
224
+ }
225
+ } catch (err) {
226
+ this.error(`Minification failed: ${err instanceof Error ? err.message : String(err)}`);
227
+ }
228
+ }
229
+
230
+ const assetRefId = this.emitFile({
231
+ type: 'asset',
232
+ [exactFileName ? 'fileName' : 'name']: name,
233
+ source: concatenatedCode,
234
+ });
235
+
236
+ const finalFileName = this.getFileName(assetRefId);
237
+
238
+ if (sourcemap && generatedMap) {
239
+
240
+ const mapFileName = `${finalFileName}.map`;
241
+
242
+ generatedMap.file = basename(finalFileName);
243
+
244
+ this.emitFile({
245
+ type: 'asset',
246
+ fileName: mapFileName,
247
+ source: JSON.stringify(generatedMap),
248
+ });
249
+
250
+ const bundleEntry = bundle[finalFileName];
251
+ if (bundleEntry && bundleEntry.type === 'asset' && typeof bundleEntry.source === 'string') {
252
+ bundleEntry.source += `\n//# sourceMappingURL=${basename(mapFileName)}`;
253
+ }
254
+ }
255
+
256
+ if (verbose) {
257
+ const fileList = sortedEntries.map(e => basename(e.filePath)).join(', ');
258
+ logger(`emitted ${name} containing: ${fileList}`, LogLevel.info);
259
+ }
260
+ },
261
+
262
+ closeBundle() {
263
+ scripts.clear();
264
+ importOrder.length = 0;
265
+ },
266
+ });
267
+ }
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "version": "0.1.0",
3
+ "license": "MIT",
4
+ "name": "@rollup-extras/plugin-script-loader",
5
+ "author": "Konstantin Shutkin",
6
+ "type": "module",
7
+ "types": "./index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./index.d.ts",
11
+ "default": "./index.js"
12
+ },
13
+ "./package.json": "./package.json"
14
+ },
15
+ "main": "./index.js",
16
+ "module": "./index.js",
17
+ "engines": {
18
+ "node": ">=22"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/kshutkin/rollup-extras.git",
23
+ "directory": "plugin-script-loader"
24
+ },
25
+ "bugs": "https://github.com/kshutkin/rollup-extras/issues",
26
+ "homepage": "https://github.com/kshutkin/rollup-extras/blob/main/plugin-script-loader/README.md",
27
+ "readme": "README.md",
28
+ "description": "Rollup plugin to mimic Webpack's script-loader inline behavior. Inlines raw scripts into the bundle in import order, enabling legacy library loading with stable ordering, terser optimization and concatenation.",
29
+ "keywords": [
30
+ "rollup-plugin",
31
+ "script-loader",
32
+ "legacy",
33
+ "inline",
34
+ "concatenation"
35
+ ],
36
+ "dependencies": {
37
+ "@niceties/logger": "^2.1.0",
38
+ "magic-string": "^0.30.21",
39
+ "@rollup-extras/utils": "^2.0.0"
40
+ },
41
+ "peerDependencies": {
42
+ "rollup": "^4.0.0"
43
+ },
44
+ "peerDependenciesMeta": {
45
+ "rollup": {
46
+ "optional": true
47
+ }
48
+ }
49
+ }