Skip to content

Commit f1247ea

Browse files
authored
Merge pull request #2 from react18-tools/autocomplete-ext
Autocomplete ext
2 parents 9fca219 + f2e2003 commit f1247ea

File tree

9 files changed

+128
-19
lines changed

9 files changed

+128
-19
lines changed

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,35 @@ console.log(myCode);
9696
// Outputs the content of 'example.js' as a string.
9797
```
9898

99+
### Good News:
100+
101+
With the latest update, you no longer need to specify the file extension explicitly.
102+
103+
```js
104+
import myCode from "./example?raw";
105+
```
106+
107+
This works seamlessly! Additionally, if you're exporting from files like `index.tsx`, `index.jsx`, etc., you can simplify imports. For example, if your file path is `my-lib/index.ts`, you can import the raw content like this:
108+
109+
```js
110+
import myCode from "./my-lib?raw";
111+
```
112+
113+
### Extension Options (Optional)
114+
115+
```ts
116+
export interface RawPluginOptions {
117+
/**
118+
* Extensions to check in order if the file does not exist.
119+
* If it's a directory, the plugin will look for `dir/index.[ext]`.
120+
* @defaultValue ["tsx", "ts", "jsx", "js", "mjs", "mts", "module.css", "module.scss", "css", "scss"]
121+
*
122+
* You can provide your own extensions to optimize build performance or extend the list based on your use case.
123+
*/
124+
ext?: string[];
125+
}
126+
```
127+
99128
### Supported File Types
100129

101130
You can use `?raw` with any file type, including:

lib/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# esbuild-raw-plugin
2+
3+
## 0.1.0
4+
5+
### Minor Changes
6+
7+
- 8a7e550: Autocomplete extensions if not added in import statement.

lib/__tests__/index.test.ts

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,45 @@
11
import { beforeAll, describe, test } from "vitest";
2-
import esbuild from "esbuild";
2+
import esbuild, { BuildOptions } from "esbuild";
33
import path from "node:path";
44
import { raw } from "../src";
55
import fs from "node:fs";
66

7+
const buildOptions: BuildOptions = {
8+
format: "cjs",
9+
target: "es2019",
10+
sourcemap: false,
11+
bundle: true,
12+
minify: true,
13+
entryPoints: [path.resolve(__dirname, "test.ts")],
14+
outdir: "__tests__/dist",
15+
treeShaking: true,
16+
plugins: [raw()],
17+
};
18+
719
describe("WebGL plugins", () => {
8-
beforeAll(async () => {
9-
await esbuild.build({
10-
format: "cjs",
11-
target: "es2019",
12-
sourcemap: false,
13-
bundle: true,
14-
minify: true,
15-
entryPoints: [path.resolve(__dirname, "test.ts")],
16-
outdir: "__tests__/dist",
17-
treeShaking: true,
18-
plugins: [raw()],
19-
});
20-
});
2120
test("test raw import", async ({ expect }) => {
21+
await esbuild.build(buildOptions);
2222
const fileContent = fs.readFileSync(path.resolve(__dirname, "../src/index.ts"), "utf-8");
2323
// @ts-ignore
2424
const generatedCodeContent = (await import("./dist/test.js")).getText();
2525
expect(fileContent).toBe(generatedCodeContent);
2626
});
27+
28+
test("test raw import with auto ext", async ({ expect }) => {
29+
await esbuild.build({ ...buildOptions, entryPoints: [path.resolve(__dirname, "test1.ts")] });
30+
const fileContent = fs.readFileSync(path.resolve(__dirname, "../src/index.ts"), "utf-8");
31+
// @ts-ignore
32+
const generatedCodeContent = (await import("./dist/test1.js")).getText();
33+
expect(fileContent).toBe(generatedCodeContent);
34+
});
35+
36+
test("throws error if no file is found", async ({ expect }) => {
37+
let didThrow = false;
38+
try {
39+
await esbuild.build({ ...buildOptions, entryPoints: [path.resolve(__dirname, "test2.ts")] });
40+
} catch (e) {
41+
didThrow = true;
42+
}
43+
expect(didThrow).toBe(true);
44+
});
2745
});

lib/__tests__/test1.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// test auto complete
2+
3+
import text from "../src?raw";
4+
5+
export const getText = () => text;

lib/__tests__/test2.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// test auto error
2+
3+
import text from "../src/my-file?raw";
4+
5+
export const getText = () => text;

lib/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "esbuild-raw-plugin",
33
"author": "Mayank Kumar Chaudhari <https://mayank-chaudhari.vercel.app>",
44
"private": false,
5-
"version": "0.0.0",
5+
"version": "0.1.0",
66
"description": "An ESBuild and TSUP plugin that allows importing files as raw text. Useful for loading code files in documentation, interactive demos, or tools like react-live.",
77
"license": "MPL-2.0",
88
"main": "./dist/index.js",

lib/src/index.ts

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,34 @@ import type { Plugin, PluginBuild } from "esbuild";
22
import fs from "node:fs";
33
import path from "node:path";
44

5+
export interface RawPluginOptions {
6+
/**
7+
* Extensions to check in order if the file does not exist.
8+
* If it's a directory, the plugin will look for `dir/index.[ext]`.
9+
* @defaultValue ["tsx", "ts", "jsx", "js", "mjs", "mts", "module.css", "module.scss", "css", "scss"]
10+
*
11+
* You can provide your own extensions to optimize build performance or extend the list based on your use case.
12+
*/
13+
ext?: string[];
14+
}
15+
516
/** Plugin to load `.glsl` files as minified strings */
6-
export const raw: () => Plugin = () => ({
17+
export const raw: (options?: RawPluginOptions) => Plugin = options => ({
718
/** generate randmo name to avoid collision among the plugins */
819
name: `raw-${(Date.now() * Math.random()).toString(36).slice(0, 8)}`,
920
setup(build: PluginBuild) {
21+
const ext = options?.ext ?? [
22+
"tsx",
23+
"ts",
24+
"jsx",
25+
"js",
26+
"mjs",
27+
"mts",
28+
"module.css",
29+
"module.scss",
30+
"css",
31+
"scss",
32+
];
1033
build.onResolve({ filter: /\?raw$/ }, args => {
1134
const filePath = args.path;
1235
return {
@@ -15,9 +38,23 @@ export const raw: () => Plugin = () => ({
1538
namespace: "raw",
1639
};
1740
});
18-
build.onLoad({ filter: /\?raw$/, namespace: "raw" }, async args => {
41+
build.onLoad({ filter: /\?raw$/, namespace: "raw" }, args => {
42+
let filePath = args.pluginData;
43+
if (fs.lstatSync(filePath).isDirectory()) filePath += path.sep + "index";
44+
if (!fs.existsSync(filePath))
45+
for (const e of ext)
46+
if (fs.existsSync(filePath + "." + e)) {
47+
filePath += "." + e;
48+
break;
49+
}
50+
if (!fs.existsSync(filePath))
51+
throw new Error(
52+
/* v8 ignore next */
53+
`File not found: ${args.pluginData}\nWe checked for following extensions: ${ext.join(", ")}. You can customise by passing {ext: [...]} to raw({ext:[...]})`,
54+
/* v8 ignore next */
55+
);
1956
return {
20-
contents: fs.readFileSync(args.pluginData, "utf8"),
57+
contents: fs.readFileSync(filePath, "utf8"),
2158
loader: "text",
2259
};
2360
});

packages/shared/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# @repo/shared
2+
3+
## 0.0.1
4+
5+
### Patch Changes
6+
7+
- Updated dependencies [8a7e550]
8+

packages/shared/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@repo/shared",
3-
"version": "0.0.0",
3+
"version": "0.0.1",
44
"private": true,
55
"sideEffects": false,
66
"main": "./dist/index.js",

0 commit comments

Comments
 (0)