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/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": "1.1.0",
3
+ "version": "2.0.0",
4
4
  "description": "Babel plugin that transforms image assets import and requires to urls / cdn",
5
- "main": "lib/index.js",
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": "cross-env NODE_ENV=production babel src --out-dir lib",
8
- "clean": "rimraf lib coverage .nyc_output",
9
- "coverage": "cross-env NODE_ENV=test nyc report --reporter=lcov",
10
- "coveralls": "cross-env NODE_ENV=test nyc report --reporter=text-lcov | coveralls",
11
- "lint": "eslint --ext js src test/**/*.spec.*",
12
- "test": "cross-env NODE_ENV=test npm run test:run",
13
- "test:run": "nyc --reporter=text-summary mocha 'test/**/*.spec.js'",
14
- "test:watch": "npm run test -- -- --watch"
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
- "babel-plugin",
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
- "devDependencies": {
43
- "babel-cli": "^6.24.1",
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
- "dependencies": {}
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
@@ -1,11 +0,0 @@
1
- {
2
- "presets": [
3
- "es2015"
4
- ],
5
- "plugins": [
6
- ],
7
- "env": {
8
- "test": {
9
- }
10
- }
11
- }
package/.editorconfig DELETED
@@ -1,15 +0,0 @@
1
- root = true
2
-
3
- [*]
4
- indent_style = space
5
- indent_size = 2
6
- end_of_line = lf
7
- charset = utf-8
8
- trim_trailing_whitespace = true
9
- insert_final_newline = true
10
-
11
- [*.{js, jsx}]
12
- quote_type = single
13
-
14
- [package.json]
15
- indent_size = 2
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/.npmignore DELETED
@@ -1,5 +0,0 @@
1
- .DS_Store
2
- src
3
- coverage
4
- tests
5
- test
package/.nycrc DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "exclude": [
3
- "tests/**/*"
4
- ],
5
- "require": [
6
- "babel-register"
7
- ]
8
- }
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
- };