babel-plugin-transform-assets-import-to-string 1.1.0 → 2.0.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 +186 -24
- package/dist/index.cjs +249 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +27 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +212 -0
- package/dist/index.js.map +1 -0
- package/package.json +45 -28
- package/.babelrc +0 -11
- package/.editorconfig +0 -15
- package/.eslintrc.json +0 -20
- package/.npmignore +0 -5
- package/.nycrc +0 -8
- package/circle.yml +0 -27
- package/lib/index.js +0 -58
- package/lib/transform.js +0 -63
- package/yarn.lock +0 -3084
package/dist/index.js
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// src/transform.ts
|
|
2
|
+
import path3 from "path";
|
|
3
|
+
|
|
4
|
+
// src/steps/fileHash.ts
|
|
5
|
+
import crypto from "crypto";
|
|
6
|
+
import fs from "fs";
|
|
7
|
+
function computeFileHash(absPath, hashLength) {
|
|
8
|
+
if (hashLength === 0) {
|
|
9
|
+
return "";
|
|
10
|
+
}
|
|
11
|
+
const content = fs.readFileSync(absPath);
|
|
12
|
+
const hash = crypto.createHash("sha1").update(content).digest("hex").slice(0, hashLength);
|
|
13
|
+
return hash;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// src/steps/buildOutputPath.ts
|
|
17
|
+
import path from "path";
|
|
18
|
+
function buildOutputPath(options) {
|
|
19
|
+
const { absPath, hash, preservePaths, projectRoot } = options;
|
|
20
|
+
const ext = path.extname(absPath);
|
|
21
|
+
const basename = path.basename(absPath, ext);
|
|
22
|
+
const hashedName = hash ? `${basename}.${hash}${ext}` : `${basename}${ext}`;
|
|
23
|
+
if (!preservePaths) {
|
|
24
|
+
return hashedName;
|
|
25
|
+
}
|
|
26
|
+
const normalizedBase = preservePaths.replace(/^\/|\/$/g, "");
|
|
27
|
+
const relativePath = path.relative(projectRoot, absPath);
|
|
28
|
+
const segments = relativePath.split(path.sep);
|
|
29
|
+
const baseIndex = segments.indexOf(normalizedBase);
|
|
30
|
+
let dirPath;
|
|
31
|
+
if (baseIndex !== -1) {
|
|
32
|
+
dirPath = segments.slice(baseIndex + 1, -1).join("/");
|
|
33
|
+
} else {
|
|
34
|
+
dirPath = path.dirname(relativePath).split(path.sep).join("/");
|
|
35
|
+
}
|
|
36
|
+
if (dirPath && dirPath !== ".") {
|
|
37
|
+
return `${dirPath}/${hashedName}`;
|
|
38
|
+
}
|
|
39
|
+
return hashedName;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/steps/copyFile.ts
|
|
43
|
+
import fs2 from "fs";
|
|
44
|
+
import path2 from "path";
|
|
45
|
+
function copyFile(options) {
|
|
46
|
+
const { absPath, outputPath, outputDir, cache } = options;
|
|
47
|
+
if (cache.pathMap.has(absPath)) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const existingSource = cache.outputMap.get(outputPath);
|
|
51
|
+
if (existingSource && existingSource !== absPath) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
`Filename collision detected (hashLength is 0)
|
|
54
|
+
- ${existingSource}
|
|
55
|
+
- ${absPath}
|
|
56
|
+
Both would output to: ${path2.join(outputDir, outputPath)}
|
|
57
|
+
Consider enabling hashLength or renaming one of the files.`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
const destPath = path2.join(outputDir, outputPath);
|
|
61
|
+
const destDir = path2.dirname(destPath);
|
|
62
|
+
if (!fs2.existsSync(destDir)) {
|
|
63
|
+
fs2.mkdirSync(destDir, { recursive: true });
|
|
64
|
+
}
|
|
65
|
+
fs2.copyFileSync(absPath, destPath);
|
|
66
|
+
cache.pathMap.set(absPath, outputPath);
|
|
67
|
+
cache.outputMap.set(outputPath, absPath);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/steps/replaceNode.ts
|
|
71
|
+
function getVariableName(node) {
|
|
72
|
+
if (node.specifiers?.[0]?.type === "ImportDefaultSpecifier") {
|
|
73
|
+
return node.specifiers[0].local.name;
|
|
74
|
+
}
|
|
75
|
+
return void 0;
|
|
76
|
+
}
|
|
77
|
+
function replaceNode(scope, uri, types) {
|
|
78
|
+
const content = types.stringLiteral(uri);
|
|
79
|
+
if (scope.callee === "require") {
|
|
80
|
+
scope.path.replaceWith(content);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const importPath = scope.path;
|
|
84
|
+
const variableName = getVariableName(importPath.node);
|
|
85
|
+
if (variableName) {
|
|
86
|
+
scope.path.replaceWith(
|
|
87
|
+
types.variableDeclaration("const", [
|
|
88
|
+
types.variableDeclarator(types.identifier(variableName), content)
|
|
89
|
+
])
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/transform.ts
|
|
95
|
+
function transform(scope, options, types, cache, projectRoot) {
|
|
96
|
+
const ext = path3.extname(scope.value);
|
|
97
|
+
if (!options.extensions || !options.extensions.includes(ext)) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const dir = path3.dirname(path3.resolve(scope.filename));
|
|
101
|
+
const absPath = path3.resolve(dir, scope.value);
|
|
102
|
+
if (absPath.includes("node_modules")) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const hashLength = options.hashLength ?? 8;
|
|
106
|
+
const hash = computeFileHash(absPath, hashLength);
|
|
107
|
+
const outputPath = buildOutputPath({
|
|
108
|
+
absPath,
|
|
109
|
+
hash,
|
|
110
|
+
preservePaths: options.preservePaths,
|
|
111
|
+
projectRoot
|
|
112
|
+
});
|
|
113
|
+
if (options.outputDir) {
|
|
114
|
+
copyFile({
|
|
115
|
+
absPath,
|
|
116
|
+
outputPath,
|
|
117
|
+
outputDir: options.outputDir,
|
|
118
|
+
cache
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
const baseUri = options.baseUri || "";
|
|
122
|
+
const separator = baseUri && !baseUri.endsWith("/") ? "/" : "";
|
|
123
|
+
const uri = `${baseUri}${separator}${outputPath}`;
|
|
124
|
+
replaceNode(scope, uri, types);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/index.ts
|
|
128
|
+
var DEFAULT_EXTENSIONS = [".gif", ".jpeg", ".jpg", ".png", ".svg"];
|
|
129
|
+
function isRequireStatement(path4) {
|
|
130
|
+
const callee = path4.get("callee");
|
|
131
|
+
return !Array.isArray(callee) && callee.isIdentifier() && callee.node.name === "require";
|
|
132
|
+
}
|
|
133
|
+
function isValidArgument(path4) {
|
|
134
|
+
const args = path4.get("arguments");
|
|
135
|
+
const arg = args[0];
|
|
136
|
+
return arg !== void 0 && arg.isStringLiteral();
|
|
137
|
+
}
|
|
138
|
+
var buildCache = null;
|
|
139
|
+
function plugin({
|
|
140
|
+
types: t
|
|
141
|
+
}) {
|
|
142
|
+
return {
|
|
143
|
+
name: "transform-assets-import-to-string",
|
|
144
|
+
pre() {
|
|
145
|
+
if (!buildCache) {
|
|
146
|
+
buildCache = {
|
|
147
|
+
pathMap: /* @__PURE__ */ new Map(),
|
|
148
|
+
outputMap: /* @__PURE__ */ new Map()
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
post() {
|
|
153
|
+
},
|
|
154
|
+
visitor: {
|
|
155
|
+
ImportDeclaration(nodePath, state) {
|
|
156
|
+
const opts = {
|
|
157
|
+
baseUri: "",
|
|
158
|
+
extensions: DEFAULT_EXTENSIONS,
|
|
159
|
+
hashLength: 8,
|
|
160
|
+
...state.opts
|
|
161
|
+
};
|
|
162
|
+
const projectRoot = state.cwd || process.cwd();
|
|
163
|
+
transform(
|
|
164
|
+
{
|
|
165
|
+
path: nodePath,
|
|
166
|
+
filename: state.filename,
|
|
167
|
+
value: nodePath.node.source.value,
|
|
168
|
+
callee: "import"
|
|
169
|
+
},
|
|
170
|
+
opts,
|
|
171
|
+
t,
|
|
172
|
+
buildCache,
|
|
173
|
+
projectRoot
|
|
174
|
+
);
|
|
175
|
+
},
|
|
176
|
+
CallExpression(nodePath, state) {
|
|
177
|
+
if (isRequireStatement(nodePath) && isValidArgument(nodePath)) {
|
|
178
|
+
const args = nodePath.get("arguments");
|
|
179
|
+
const arg = args[0];
|
|
180
|
+
if (!arg.isStringLiteral()) return;
|
|
181
|
+
const opts = {
|
|
182
|
+
baseUri: "",
|
|
183
|
+
extensions: DEFAULT_EXTENSIONS,
|
|
184
|
+
hashLength: 8,
|
|
185
|
+
...state.opts
|
|
186
|
+
};
|
|
187
|
+
const projectRoot = state.cwd || process.cwd();
|
|
188
|
+
transform(
|
|
189
|
+
{
|
|
190
|
+
path: nodePath,
|
|
191
|
+
filename: state.filename,
|
|
192
|
+
value: arg.node.value,
|
|
193
|
+
callee: "require"
|
|
194
|
+
},
|
|
195
|
+
opts,
|
|
196
|
+
t,
|
|
197
|
+
buildCache,
|
|
198
|
+
projectRoot
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function resetBuildCache() {
|
|
206
|
+
buildCache = null;
|
|
207
|
+
}
|
|
208
|
+
export {
|
|
209
|
+
plugin as default,
|
|
210
|
+
resetBuildCache
|
|
211
|
+
};
|
|
212
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/transform.ts","../src/steps/fileHash.ts","../src/steps/buildOutputPath.ts","../src/steps/copyFile.ts","../src/steps/replaceNode.ts","../src/index.ts"],"sourcesContent":["import path from 'node:path';\nimport type { types as t } from '@babel/core';\nimport { computeFileHash } from './steps/fileHash.js';\nimport { buildOutputPath } from './steps/buildOutputPath.js';\nimport { copyFile } from './steps/copyFile.js';\nimport { replaceNode } from './steps/replaceNode.js';\nimport type { PluginOptions, TransformScope, CopyCache } from './types.js';\n\nexport function transform(\n scope: TransformScope,\n options: PluginOptions,\n types: typeof t,\n cache: CopyCache,\n projectRoot: string\n): void {\n const ext = path.extname(scope.value);\n\n if (!options.extensions || !options.extensions.includes(ext)) {\n return;\n }\n\n const dir = path.dirname(path.resolve(scope.filename));\n const absPath = path.resolve(dir, scope.value);\n\n // Skip node_modules\n if (absPath.includes('node_modules')) {\n return;\n }\n\n // Compute content hash\n const hashLength = options.hashLength ?? 8;\n const hash = computeFileHash(absPath, hashLength);\n\n // Build output path\n const outputPath = buildOutputPath({\n absPath,\n hash,\n preservePaths: options.preservePaths,\n projectRoot,\n });\n\n // Copy file if outputDir is set\n if (options.outputDir) {\n copyFile({\n absPath,\n outputPath,\n outputDir: options.outputDir,\n cache,\n });\n }\n\n // Build final URI\n const baseUri = options.baseUri || '';\n const separator = baseUri && !baseUri.endsWith('/') ? '/' : '';\n const uri = `${baseUri}${separator}${outputPath}`;\n\n replaceNode(scope, uri, types);\n}\n","import crypto from 'node:crypto';\nimport fs from 'node:fs';\n\n/**\n * Compute SHA1 content hash of a file\n * @param absPath - Absolute path to the file\n * @param hashLength - Number of hex characters to return (0 = no hash)\n * @returns Hash string or empty string if hashLength is 0\n */\nexport function computeFileHash(absPath: string, hashLength: number): string {\n if (hashLength === 0) {\n return '';\n }\n\n const content = fs.readFileSync(absPath);\n\n const hash = crypto\n .createHash('sha1')\n .update(content)\n .digest('hex')\n .slice(0, hashLength);\n\n return hash;\n}\n","import path from 'node:path';\n\nexport interface BuildOutputPathOptions {\n absPath: string;\n hash: string;\n preservePaths: string | undefined;\n projectRoot: string;\n}\n\nexport function buildOutputPath(options: BuildOutputPathOptions): string {\n const { absPath, hash, preservePaths, projectRoot } = options;\n\n const ext = path.extname(absPath);\n const basename = path.basename(absPath, ext);\n const hashedName = hash ? `${basename}.${hash}${ext}` : `${basename}${ext}`;\n\n if (!preservePaths) {\n return hashedName;\n }\n\n // Normalize preservePaths: strip leading/trailing slashes\n const normalizedBase = preservePaths.replace(/^\\/|\\/$/g, '');\n\n // Get relative path from project root\n const relativePath = path.relative(projectRoot, absPath);\n\n // Find the preservePaths segment in the path\n const segments = relativePath.split(path.sep);\n const baseIndex = segments.indexOf(normalizedBase);\n\n let dirPath: string;\n if (baseIndex !== -1) {\n // Strip everything up to and including the base\n dirPath = segments.slice(baseIndex + 1, -1).join('/');\n } else {\n // Base not found, use full relative directory path\n dirPath = path.dirname(relativePath).split(path.sep).join('/');\n }\n\n if (dirPath && dirPath !== '.') {\n return `${dirPath}/${hashedName}`;\n }\n\n return hashedName;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { CopyCache } from '../types.js';\n\nexport interface CopyFileOptions {\n absPath: string;\n outputPath: string;\n outputDir: string;\n cache: CopyCache;\n}\n\nexport function copyFile(options: CopyFileOptions): void {\n const { absPath, outputPath, outputDir, cache } = options;\n\n // Check if already copied from this source\n if (cache.pathMap.has(absPath)) {\n return;\n }\n\n // Check for collision (different source, same output)\n const existingSource = cache.outputMap.get(outputPath);\n if (existingSource && existingSource !== absPath) {\n throw new Error(\n `Filename collision detected (hashLength is 0)\\n` +\n ` - ${existingSource}\\n` +\n ` - ${absPath}\\n` +\n ` Both would output to: ${path.join(outputDir, outputPath)}\\n` +\n ` Consider enabling hashLength or renaming one of the files.`\n );\n }\n\n // Build full destination path\n const destPath = path.join(outputDir, outputPath);\n const destDir = path.dirname(destPath);\n\n // Create directories if needed\n if (!fs.existsSync(destDir)) {\n fs.mkdirSync(destDir, { recursive: true });\n }\n\n // Copy the file\n fs.copyFileSync(absPath, destPath);\n\n // Update cache\n cache.pathMap.set(absPath, outputPath);\n cache.outputMap.set(outputPath, absPath);\n}\n","import type { types as t } from '@babel/core';\nimport type { TransformScope } from '../types.js';\n\nfunction getVariableName(node: t.ImportDeclaration): string | undefined {\n if (node.specifiers?.[0]?.type === 'ImportDefaultSpecifier') {\n return node.specifiers[0].local.name;\n }\n return undefined;\n}\n\nexport function replaceNode(\n scope: TransformScope,\n uri: string,\n types: typeof t\n): void {\n const content = types.stringLiteral(uri);\n\n if (scope.callee === 'require') {\n scope.path.replaceWith(content);\n return;\n }\n\n const importPath = scope.path as import('@babel/core').NodePath<t.ImportDeclaration>;\n const variableName = getVariableName(importPath.node);\n\n if (variableName) {\n scope.path.replaceWith(\n types.variableDeclaration('const', [\n types.variableDeclarator(types.identifier(variableName), content),\n ])\n );\n }\n}\n","import type { PluginObj, NodePath } from '@babel/core';\nimport type { ImportDeclaration, CallExpression } from '@babel/types';\nimport { transform } from './transform.js';\nimport type { PluginOptions, CopyCache } from './types.js';\n\nconst DEFAULT_EXTENSIONS = ['.gif', '.jpeg', '.jpg', '.png', '.svg'];\n\nfunction isRequireStatement(path: NodePath<CallExpression>): boolean {\n const callee = path.get('callee');\n return (\n !Array.isArray(callee) &&\n callee.isIdentifier() &&\n callee.node.name === 'require'\n );\n}\n\nfunction isValidArgument(path: NodePath<CallExpression>): boolean {\n const args = path.get('arguments');\n const arg = args[0];\n return arg !== undefined && arg.isStringLiteral();\n}\n\ninterface PluginState {\n opts: PluginOptions;\n filename: string;\n cwd: string;\n}\n\n// Module-level cache shared across all files in a build\nlet buildCache: CopyCache | null = null;\n\nexport default function plugin({\n types: t,\n}: {\n types: typeof import('@babel/types');\n}): PluginObj<PluginState> {\n return {\n name: 'transform-assets-import-to-string',\n pre() {\n // Initialize cache at start of build if not exists\n if (!buildCache) {\n buildCache = {\n pathMap: new Map(),\n outputMap: new Map(),\n };\n }\n },\n post() {\n // Clear cache after build completes\n // Note: This runs per-file, so we don't clear here\n // Cache persists for the entire build\n },\n visitor: {\n ImportDeclaration(\n nodePath: NodePath<ImportDeclaration>,\n state: PluginState\n ) {\n const opts: PluginOptions = {\n baseUri: '',\n extensions: DEFAULT_EXTENSIONS,\n hashLength: 8,\n ...state.opts,\n };\n\n const projectRoot = state.cwd || process.cwd();\n\n transform(\n {\n path: nodePath,\n filename: state.filename,\n value: nodePath.node.source.value,\n callee: 'import',\n },\n opts,\n t,\n buildCache!,\n projectRoot\n );\n },\n CallExpression(nodePath: NodePath<CallExpression>, state: PluginState) {\n if (isRequireStatement(nodePath) && isValidArgument(nodePath)) {\n const args = nodePath.get('arguments');\n const arg = args[0];\n\n if (!arg.isStringLiteral()) return;\n\n const opts: PluginOptions = {\n baseUri: '',\n extensions: DEFAULT_EXTENSIONS,\n hashLength: 8,\n ...state.opts,\n };\n\n const projectRoot = state.cwd || process.cwd();\n\n transform(\n {\n path: nodePath,\n filename: state.filename,\n value: arg.node.value,\n callee: 'require',\n },\n opts,\n t,\n buildCache!,\n projectRoot\n );\n }\n },\n },\n };\n}\n\n// Export for testing - allows resetting cache between test runs\nexport function resetBuildCache(): void {\n buildCache = null;\n}\n\nexport type { PluginOptions } from './types.js';\n"],"mappings":"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","names":["path","fs","path","path","path"]}
|
package/package.json
CHANGED
|
@@ -1,17 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "babel-plugin-transform-assets-import-to-string",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Babel plugin that transforms image assets import and requires to urls / cdn",
|
|
5
|
-
"
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"require": "./dist/index.cjs"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"main": "./dist/index.cjs",
|
|
14
|
+
"module": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=20"
|
|
21
|
+
},
|
|
6
22
|
"scripts": {
|
|
7
|
-
"build": "
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
23
|
+
"build": "tsup",
|
|
24
|
+
"dev": "tsup --watch",
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"test:watch": "vitest",
|
|
27
|
+
"test:coverage": "vitest run --coverage",
|
|
28
|
+
"lint": "eslint src test",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"clean": "rm -rf dist .turbo",
|
|
31
|
+
"check": "turbo lint typecheck test"
|
|
15
32
|
},
|
|
16
33
|
"repository": {
|
|
17
34
|
"type": "git",
|
|
@@ -19,19 +36,17 @@
|
|
|
19
36
|
},
|
|
20
37
|
"keywords": [
|
|
21
38
|
"babel",
|
|
39
|
+
"babel-plugin",
|
|
22
40
|
"import",
|
|
23
41
|
"assets",
|
|
24
42
|
"cdn",
|
|
25
43
|
"images",
|
|
26
44
|
"isomorphic",
|
|
27
45
|
"server-side-rendering",
|
|
28
|
-
"
|
|
29
|
-
"plugin",
|
|
30
|
-
"require",
|
|
46
|
+
"ssr",
|
|
31
47
|
"transform",
|
|
32
48
|
"string",
|
|
33
|
-
"universal"
|
|
34
|
-
"webpack"
|
|
49
|
+
"universal"
|
|
35
50
|
],
|
|
36
51
|
"author": "Gerald Yeo <contact@fusedthought.com>",
|
|
37
52
|
"license": "MIT",
|
|
@@ -39,18 +54,20 @@
|
|
|
39
54
|
"url": "https://github.com/yeojz/babel-plugin-transform-assets-import-to-string/issues"
|
|
40
55
|
},
|
|
41
56
|
"homepage": "https://github.com/yeojz/babel-plugin-transform-assets-import-to-string#readme",
|
|
42
|
-
"
|
|
43
|
-
"babel
|
|
44
|
-
"babel-eslint": "^8.0.0",
|
|
45
|
-
"babel-preset-es2015": "^6.24.1",
|
|
46
|
-
"babel-register": "^6.24.1",
|
|
47
|
-
"chai": "^4.0.0",
|
|
48
|
-
"coveralls": "^3.0.0",
|
|
49
|
-
"cross-env": "^5.0.0",
|
|
50
|
-
"eslint": "^4.1.0",
|
|
51
|
-
"mocha": "^4.0.0",
|
|
52
|
-
"nyc": "^11.0.2",
|
|
53
|
-
"rimraf": "^2.6.1"
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"@babel/core": "^7.20.0"
|
|
54
59
|
},
|
|
55
|
-
"
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@babel/core": "^7.20.0",
|
|
62
|
+
"@types/babel__core": "^7.20.0",
|
|
63
|
+
"@types/node": "^20.0.0",
|
|
64
|
+
"@vitest/coverage-v8": "^2.1.9",
|
|
65
|
+
"eslint": "^9.0.0",
|
|
66
|
+
"prettier": "^3.0.0",
|
|
67
|
+
"tsup": "^8.0.0",
|
|
68
|
+
"turbo": "^2.0.0",
|
|
69
|
+
"typescript": "~5.5.0",
|
|
70
|
+
"typescript-eslint": "^8.0.0",
|
|
71
|
+
"vitest": "^2.0.0"
|
|
72
|
+
}
|
|
56
73
|
}
|
package/.babelrc
DELETED
package/.editorconfig
DELETED
package/.eslintrc.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"parser": "babel-eslint",
|
|
3
|
-
"env": {
|
|
4
|
-
"browser": true,
|
|
5
|
-
"es6": true,
|
|
6
|
-
"node": true,
|
|
7
|
-
"mocha" : true
|
|
8
|
-
},
|
|
9
|
-
"parserOptions": {
|
|
10
|
-
"ecmaVersion": 6,
|
|
11
|
-
"sourceType": "module",
|
|
12
|
-
"ecmaFeatures": {
|
|
13
|
-
"experimentalObjectRestSpread": true,
|
|
14
|
-
"jsx": true
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"extends": [
|
|
18
|
-
"eslint:recommended"
|
|
19
|
-
]
|
|
20
|
-
}
|
package/.nycrc
DELETED
package/circle.yml
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
machine:
|
|
2
|
-
node:
|
|
3
|
-
version: "6"
|
|
4
|
-
general:
|
|
5
|
-
branches:
|
|
6
|
-
ignore:
|
|
7
|
-
- gh-pages
|
|
8
|
-
test:
|
|
9
|
-
pre:
|
|
10
|
-
- npm run clean
|
|
11
|
-
override:
|
|
12
|
-
- npm run test
|
|
13
|
-
- npm run lint
|
|
14
|
-
deployment:
|
|
15
|
-
coverage:
|
|
16
|
-
branch: [master, /^hotfix\/.*$/, /^feature\/.*$/]
|
|
17
|
-
commands:
|
|
18
|
-
- npm run coveralls
|
|
19
|
-
release:
|
|
20
|
-
tag: /^v[0-9]+(\.[0-9]+)*$/
|
|
21
|
-
owner: yeojz
|
|
22
|
-
commands:
|
|
23
|
-
- npm run clean
|
|
24
|
-
- npm run build
|
|
25
|
-
- echo -e "$NPM_USER\n$NPM_PASS\n$NPM_EMAIL" | npm login
|
|
26
|
-
- npm publish
|
|
27
|
-
- npm logout
|
package/lib/index.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.defaultOptions = undefined;
|
|
7
|
-
exports.transformImportsInline = transformImportsInline;
|
|
8
|
-
|
|
9
|
-
var _path = require('path');
|
|
10
|
-
|
|
11
|
-
var _transform = require('./transform');
|
|
12
|
-
|
|
13
|
-
var _transform2 = _interopRequireDefault(_transform);
|
|
14
|
-
|
|
15
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
-
|
|
17
|
-
var defaultOptions = exports.defaultOptions = {
|
|
18
|
-
flatten: false,
|
|
19
|
-
extensions: ['.gif', '.jpeg', '.jpg', '.png', '.svg']
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
var applyTransform = function applyTransform(p, t, state, value, calleeName) {
|
|
23
|
-
var ext = (0, _path.extname)(value);
|
|
24
|
-
var options = Object.assign({}, defaultOptions, state.opts);
|
|
25
|
-
|
|
26
|
-
if (options.extensions && options.extensions.indexOf(ext) >= 0) {
|
|
27
|
-
var dir = (0, _path.dirname)((0, _path.resolve)(state.file.opts.filename));
|
|
28
|
-
var absPath = (0, _path.resolve)(dir, value);
|
|
29
|
-
(0, _transform2.default)(p, t, options, absPath, calleeName);
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
function transformImportsInline(_ref) {
|
|
34
|
-
var t = _ref.types;
|
|
35
|
-
|
|
36
|
-
return {
|
|
37
|
-
visitor: {
|
|
38
|
-
ImportDeclaration: function ImportDeclaration(p, state) {
|
|
39
|
-
applyTransform(p, t, state, p.node.source.value, 'import');
|
|
40
|
-
},
|
|
41
|
-
CallExpression: function CallExpression(p, state) {
|
|
42
|
-
var callee = p.get('callee');
|
|
43
|
-
if (!callee.isIdentifier() || !callee.equals('name', 'require')) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
var arg = p.get('arguments')[0];
|
|
48
|
-
if (!arg || !arg.isStringLiteral()) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
applyTransform(p, t, state, arg.node.value, 'require');
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
exports.default = transformImportsInline;
|
package/lib/transform.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
|
|
7
|
-
var _crypto = require('crypto');
|
|
8
|
-
|
|
9
|
-
var _crypto2 = _interopRequireDefault(_crypto);
|
|
10
|
-
|
|
11
|
-
var _fs = require('fs');
|
|
12
|
-
|
|
13
|
-
var _fs2 = _interopRequireDefault(_fs);
|
|
14
|
-
|
|
15
|
-
var _path = require('path');
|
|
16
|
-
|
|
17
|
-
var _path2 = _interopRequireDefault(_path);
|
|
18
|
-
|
|
19
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
20
|
-
|
|
21
|
-
function getHash(str) {
|
|
22
|
-
return _crypto2.default.createHash('sha1').update(str, 'utf8').digest('hex').slice(0, 8);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function getFile(absPath, baseDir, uri, flatten) {
|
|
26
|
-
var file = absPath.split(baseDir || _path2.default.sep).pop();
|
|
27
|
-
|
|
28
|
-
if (!baseDir) {
|
|
29
|
-
return uri ? '/' + file : file;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
var fileName = flatten ? _path2.default.basename(file) : file;
|
|
33
|
-
|
|
34
|
-
return _path2.default.join(baseDir, fileName).replace(/\\/g, '/').replace(/\/\/g/, '/');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
var getVariableName = function getVariableName(p) {
|
|
38
|
-
if (p.node.specifiers && p.node.specifiers[0] && p.node.specifiers[0].local) {
|
|
39
|
-
return p.node.specifiers[0].local.name;
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
exports.default = function (p, t, opts, absPath, calleeName) {
|
|
44
|
-
var file = getFile(absPath, opts.baseDir, opts.baseUri, opts.flatten);
|
|
45
|
-
var hash = '';
|
|
46
|
-
|
|
47
|
-
if (opts.hash === 1) {
|
|
48
|
-
var content = _fs2.default.readFileSync(absPath, 'utf8').trim();
|
|
49
|
-
hash = '?' + getHash(content);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
var uri = '' + (opts.baseUri || '') + file + hash;
|
|
53
|
-
|
|
54
|
-
if (calleeName === 'require') {
|
|
55
|
-
p.replaceWith(t.StringLiteral(uri));
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
var variableName = getVariableName(p);
|
|
60
|
-
if (variableName) {
|
|
61
|
-
p.replaceWith(t.variableDeclaration('const', [t.variableDeclarator(t.identifier(variableName), t.stringLiteral(uri))]));
|
|
62
|
-
}
|
|
63
|
-
};
|