nexfpack 0.1.1 → 0.1.3
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 +20 -20
- package/README-CN.md +100 -99
- package/README.md +1 -0
- package/cli.mjs +64 -12
- package/index.d.mts +1 -0
- package/index.mjs +100 -92
- package/package.json +2 -1
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Nexfteam
|
|
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
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nexfteam
|
|
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
21
|
SOFTWARE.
|
package/README-CN.md
CHANGED
|
@@ -1,99 +1,100 @@
|
|
|
1
|
-
# Nexfpack
|
|
2
|
-
|
|
3
|
-
语言: [English](https://github.com/nexfteam/Nexfpack/blob/main/README.md) | 简体中文(当前)
|
|
4
|
-
|
|
5
|
-
一个用于将Node.js脚本或模块打包为单个可执行文件的工具。
|
|
6
|
-
|
|
7
|
-
## 安装
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install -g nexfpack
|
|
11
|
-
# or
|
|
12
|
-
pnpm add -g nexfpack
|
|
13
|
-
# or
|
|
14
|
-
yarn global add nexfpack
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## 快速开始
|
|
18
|
-
|
|
19
|
-
### CLI命令
|
|
20
|
-
|
|
21
|
-
创建 `nexfpack.config.json` 配置文件并运行以下CLI命令:
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
nexfpack nexfpack.config.json
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
### CommonJS API
|
|
28
|
-
|
|
29
|
-
```javascript
|
|
30
|
-
const nexfpack = require('nexfpack');
|
|
31
|
-
|
|
32
|
-
const config = {
|
|
33
|
-
"name": "my-app",
|
|
34
|
-
"entry": "index.js",
|
|
35
|
-
"output": "dist",
|
|
36
|
-
"ignore": [".gitignore", "README.md"],
|
|
37
|
-
"autoRun": true
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
nexfpack(config);
|
|
41
|
-
|
|
42
|
-
// 或者使用配置文件
|
|
43
|
-
// nexfpack({configFile: 'nexfpack.config.json'})
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### ESM API
|
|
47
|
-
|
|
48
|
-
```javascript
|
|
49
|
-
import nexfpack from 'nexfpack';
|
|
50
|
-
|
|
51
|
-
const config = {
|
|
52
|
-
"name": "my-app",
|
|
53
|
-
"entry": "index.js",
|
|
54
|
-
"output": "dist",
|
|
55
|
-
"ignore": [".gitignore", "README.md"],
|
|
56
|
-
"autoRun": true
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
nexfpack(config);
|
|
60
|
-
|
|
61
|
-
// 或者使用配置文件
|
|
62
|
-
// nexfpack({configFile: 'nexfpack.config.json'})
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### 配置文件示例
|
|
66
|
-
|
|
67
|
-
```json
|
|
68
|
-
{
|
|
69
|
-
"name": "my-app",
|
|
70
|
-
"entry": "index.js",
|
|
71
|
-
"output": "dist",
|
|
72
|
-
"ignore": [".gitignore", "README.md"],
|
|
73
|
-
"autoRun": true
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## 配置项
|
|
78
|
-
|
|
79
|
-
| 名称 | 类型 | 描述 | 默认值 |
|
|
80
|
-
| --- | --- | --- | --- |
|
|
81
|
-
| name | string | 应用名称 | `nexfpack-app` |
|
|
82
|
-
| root | string | 根目录 | 若使用配置文件,则为文件所在目录,否则为 `process.cwd()` |
|
|
83
|
-
| relativeRoot | boolean | `root` 是否为相对路径 | `false` |
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
1
|
+
# Nexfpack
|
|
2
|
+
|
|
3
|
+
语言: [English](https://github.com/nexfteam/Nexfpack/blob/main/README.md) | 简体中文(当前)
|
|
4
|
+
|
|
5
|
+
一个用于将Node.js脚本或模块打包为单个可执行文件的工具。
|
|
6
|
+
|
|
7
|
+
## 安装
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g nexfpack
|
|
11
|
+
# or
|
|
12
|
+
pnpm add -g nexfpack
|
|
13
|
+
# or
|
|
14
|
+
yarn global add nexfpack
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 快速开始
|
|
18
|
+
|
|
19
|
+
### CLI命令
|
|
20
|
+
|
|
21
|
+
创建 `nexfpack.config.json` 配置文件并运行以下CLI命令:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
nexfpack nexfpack.config.json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### CommonJS API
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
const nexfpack = require('nexfpack');
|
|
31
|
+
|
|
32
|
+
const config = {
|
|
33
|
+
"name": "my-app",
|
|
34
|
+
"entry": "index.js",
|
|
35
|
+
"output": "dist",
|
|
36
|
+
"ignore": [".gitignore", "README.md"],
|
|
37
|
+
"autoRun": true
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
nexfpack(config);
|
|
41
|
+
|
|
42
|
+
// 或者使用配置文件
|
|
43
|
+
// nexfpack({configFile: 'nexfpack.config.json'})
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### ESM API
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
import nexfpack from 'nexfpack';
|
|
50
|
+
|
|
51
|
+
const config = {
|
|
52
|
+
"name": "my-app",
|
|
53
|
+
"entry": "index.js",
|
|
54
|
+
"output": "dist",
|
|
55
|
+
"ignore": [".gitignore", "README.md"],
|
|
56
|
+
"autoRun": true
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
nexfpack(config);
|
|
60
|
+
|
|
61
|
+
// 或者使用配置文件
|
|
62
|
+
// nexfpack({configFile: 'nexfpack.config.json'})
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 配置文件示例
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"name": "my-app",
|
|
70
|
+
"entry": "index.js",
|
|
71
|
+
"output": "dist",
|
|
72
|
+
"ignore": [".gitignore", "README.md"],
|
|
73
|
+
"autoRun": true
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 配置项
|
|
78
|
+
|
|
79
|
+
| 名称 | 类型 | 描述 | 默认值 |
|
|
80
|
+
| --- | --- | --- | --- |
|
|
81
|
+
| name | string | 应用名称 | `nexfpack-app` |
|
|
82
|
+
| root | string | 根目录 | 若使用配置文件,则为文件所在目录,否则为 `process.cwd()` |
|
|
83
|
+
| relativeRoot | boolean | `root` 是否为相对路径 | `false` |
|
|
84
|
+
| log | boolean | 是否打印日志 | `true` |
|
|
85
|
+
| entry | string | 入口文件路径 | `index.js` |
|
|
86
|
+
| output | string | 输出目录 | `dist` |
|
|
87
|
+
| tempdir | string | 打包过程中的临时目录 | `.nexfpack-temp` |
|
|
88
|
+
| autoDeleteTempFiles | boolean | 是否自动删除临时文件 | `true` |
|
|
89
|
+
| ignorefile | string | 忽略文件路径,优先级高于 `ignore` | `.nexfpackignore` |
|
|
90
|
+
| ignore | array | 忽略的文件或目录,支持 glob 语法 | `[]` |
|
|
91
|
+
| enabledSign | boolean | 是否启用签名(暂不支持) | `false` |
|
|
92
|
+
| autoRun | boolean | 是否自动运行打包后的可执行文件 | `false` |
|
|
93
|
+
|
|
94
|
+
## 环境要求
|
|
95
|
+
|
|
96
|
+
- Node.js >= 20.12.0
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
MIT
|
package/README.md
CHANGED
|
@@ -81,6 +81,7 @@ nexfpack(config);
|
|
|
81
81
|
| name | string | Application name | `nexfpack-app` |
|
|
82
82
|
| root | string | Root directory | The directory of the config file if specified, otherwise `process.cwd()` |
|
|
83
83
|
| relativeRoot | boolean | Whether `root` is a relative path | `false` |
|
|
84
|
+
| log | boolean | Whether to print logs | `true` |
|
|
84
85
|
| entry | string | Entry file path | `index.js` |
|
|
85
86
|
| output | string | Output directory | `dist` |
|
|
86
87
|
| tempdir | string | Temporary directory for the build process | `.nexfpack-temp` |
|
package/cli.mjs
CHANGED
|
@@ -1,13 +1,65 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import nexfpack from "./index.mjs";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import nexfpack from "./index.mjs";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
|
|
5
|
+
const args = process.argv.slice(2);
|
|
6
|
+
if(args.length === 0) {
|
|
7
|
+
console.log("Usage: nexfpack <config-file-path>");
|
|
8
|
+
console.log("Use nexfpack --help for more info.")
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
const configFilePath = args[0];
|
|
12
|
+
|
|
13
|
+
if(configFilePath === "--help" || configFilePath === "-h") {
|
|
14
|
+
console.log(
|
|
15
|
+
`
|
|
16
|
+
__ _ __ _
|
|
17
|
+
/ \\ / /\\_____\\ \\ / /
|
|
18
|
+
/ /\\ \\ / / / ____/\\ \\/ /
|
|
19
|
+
/ / /\\ \\/ / / /____\\/\\ /_____
|
|
20
|
+
/_/ / \\__/ / ____/\\ / \\ ___\\
|
|
21
|
+
\\_\\/ \\_\\/ /____\\/ / /\\ \\ \\__/
|
|
22
|
+
/_____/\\ /_/ \\_\\ __\\
|
|
23
|
+
\\_____\\/ \\ \\ \\_/
|
|
24
|
+
\\ \\_\\
|
|
25
|
+
_______ _____ \\/_/__
|
|
26
|
+
| ___ | /\\ | ___| | | / /
|
|
27
|
+
| |___| | / \\ | | | |/ /
|
|
28
|
+
| _____| / /\\ \\ | | | |
|
|
29
|
+
| | / ____ \\ | |___ | |\\ \\
|
|
30
|
+
|_| /_/ \\_\\ |_____| |_| \\_\\
|
|
31
|
+
|
|
32
|
+
`)
|
|
33
|
+
console.log("Nexfpack - A tool for building single executable files from Node.js scripts or modules.");
|
|
34
|
+
|
|
35
|
+
console.log("Version: " + JSON.parse(fs.readFileSync("./package.json", "utf8")).version);
|
|
36
|
+
|
|
37
|
+
const helpText = `
|
|
38
|
+
Usage: nexfpack <config-file-path>
|
|
39
|
+
|
|
40
|
+
Arguments:
|
|
41
|
+
configFile Path to JSON config file (default: ./nexfpack.config.json)
|
|
42
|
+
|
|
43
|
+
Options:
|
|
44
|
+
--help Show this help message
|
|
45
|
+
|
|
46
|
+
Examples:
|
|
47
|
+
nexfpack ./my-config.json # Use custom config file
|
|
48
|
+
|
|
49
|
+
Config file example (nexfpack.config.json):
|
|
50
|
+
{
|
|
51
|
+
"name": "my-app",
|
|
52
|
+
"entry": "index.js",
|
|
53
|
+
"output": "dist",
|
|
54
|
+
"ignore": [".gitignore", "README.md"],
|
|
55
|
+
"autoRun": true
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
For more details, visit: https://github.com/nexfteam/Nexfpack`
|
|
59
|
+
console.log(helpText);
|
|
60
|
+
process.exit(0);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
nexfpack({
|
|
64
|
+
configFile: configFilePath,
|
|
13
65
|
});
|
package/index.d.mts
CHANGED
package/index.mjs
CHANGED
|
@@ -42,6 +42,7 @@ async function fillOptions(options) {
|
|
|
42
42
|
return {
|
|
43
43
|
name: options.name ?? 'nexfpack-app',
|
|
44
44
|
root: cwd,
|
|
45
|
+
log: options.log ?? true,
|
|
45
46
|
entry: path.resolve(cwd, options.entry ?? 'index.js'),
|
|
46
47
|
output: path.resolve(cwd, options.output ?? 'dist'),
|
|
47
48
|
tempdir: path.resolve(cwd, options.tempdir ?? '.nexfpack-temp'),
|
|
@@ -67,35 +68,19 @@ function listAllFiles(dir) {
|
|
|
67
68
|
return result;
|
|
68
69
|
}
|
|
69
70
|
async function nexfpack(options) {
|
|
71
|
+
let config;
|
|
72
|
+
if (options.configFile) {
|
|
73
|
+
config = JSON.parse(fs.readFileSync(options.configFile, 'utf8'));
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
config = options;
|
|
77
|
+
}
|
|
78
|
+
const filledConfig = await fillOptions(config);
|
|
70
79
|
try {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
/ /\\ \\ / / / ____/\\ \\/ /
|
|
75
|
-
/ / /\\ \\/ / / /____\\/\\ /_____
|
|
76
|
-
/_/ / \\__/ / ____/\\ / \\ ___\\
|
|
77
|
-
\\_\\/ \\_\\/ /____\\/ / /\\ \\ \\__/
|
|
78
|
-
/_____/\\ /_/ \\_\\ __\\
|
|
79
|
-
\\_____\\/ \\ \\ \\_/
|
|
80
|
-
\\ \\_\\
|
|
81
|
-
_______ _____ \\/_/__
|
|
82
|
-
| ___ | /\\ | ___| | | / /
|
|
83
|
-
| |___| | / \\ | | | |/ /
|
|
84
|
-
| _____| / /\\ \\ | | | |
|
|
85
|
-
| | / ____ \\ | |___ | |\\ \\
|
|
86
|
-
|_| /_/ \\_\\ |_____| |_| \\_\\
|
|
87
|
-
|
|
88
|
-
`);
|
|
89
|
-
console.log('▶️ Start packing...');
|
|
90
|
-
console.log('🧪 Tips: Nexfpack is very experimental. It may have some errors.');
|
|
91
|
-
let config;
|
|
92
|
-
if (options.configFile) {
|
|
93
|
-
config = JSON.parse(fs.readFileSync(options.configFile, 'utf8'));
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
config = options;
|
|
80
|
+
if (filledConfig.log) {
|
|
81
|
+
console.log('▶ Start packing...');
|
|
82
|
+
console.log('🧪 Tips: Nexfpack is very experimental. It may have some errors.');
|
|
97
83
|
}
|
|
98
|
-
const filledConfig = await fillOptions(config);
|
|
99
84
|
if (!fs.existsSync(filledConfig.tempdir)) {
|
|
100
85
|
fs.mkdirSync(filledConfig.tempdir, { recursive: true });
|
|
101
86
|
}
|
|
@@ -103,14 +88,18 @@ async function nexfpack(options) {
|
|
|
103
88
|
fs.rmSync(filledConfig.tempdir, { recursive: true, force: true });
|
|
104
89
|
fs.mkdirSync(filledConfig.tempdir, { recursive: true });
|
|
105
90
|
}
|
|
106
|
-
|
|
91
|
+
if (filledConfig.log) {
|
|
92
|
+
console.log('📄 Copying files...');
|
|
93
|
+
}
|
|
107
94
|
if (!fs.existsSync(path.join(filledConfig.tempdir, 'source-copy'))) {
|
|
108
95
|
fs.mkdirSync(path.join(filledConfig.tempdir, 'source-copy'), { recursive: true });
|
|
109
96
|
}
|
|
110
97
|
await new Promise((resolve, reject) => {
|
|
111
98
|
copyfiles([filledConfig.root, path.join(filledConfig.tempdir, 'source-copy')], { up: 1, exclude: filledConfig.ignore }, (err) => {
|
|
112
99
|
if (err) {
|
|
113
|
-
|
|
100
|
+
if (filledConfig.log) {
|
|
101
|
+
console.error('❌ Failed to copy files:', err);
|
|
102
|
+
}
|
|
114
103
|
reject(err);
|
|
115
104
|
}
|
|
116
105
|
else {
|
|
@@ -118,11 +107,15 @@ async function nexfpack(options) {
|
|
|
118
107
|
}
|
|
119
108
|
});
|
|
120
109
|
});
|
|
121
|
-
|
|
110
|
+
if (filledConfig.log) {
|
|
111
|
+
console.log('📜 Packing source...');
|
|
112
|
+
}
|
|
122
113
|
const tarStream = packTar(path.join(filledConfig.tempdir, 'source-copy'));
|
|
123
114
|
const writeStream = fs.createWriteStream(path.join(filledConfig.tempdir, 'source.tar'));
|
|
124
115
|
await pipeline(tarStream, writeStream);
|
|
125
|
-
|
|
116
|
+
if (filledConfig.log) {
|
|
117
|
+
console.log('📦 Packing executable...');
|
|
118
|
+
}
|
|
126
119
|
fs.writeFileSync(path.join(filledConfig.tempdir, 'package.json'), JSON.stringify({
|
|
127
120
|
name: filledConfig.name,
|
|
128
121
|
version: '1.0.0',
|
|
@@ -134,7 +127,10 @@ async function nexfpack(options) {
|
|
|
134
127
|
}, null, 2));
|
|
135
128
|
const installSpawnResult = child_process.spawnSync('npm install --omit=dev', { stdio: 'inherit', cwd: filledConfig.tempdir, shell: true });
|
|
136
129
|
if (installSpawnResult.status !== 0) {
|
|
137
|
-
|
|
130
|
+
if (filledConfig.log) {
|
|
131
|
+
console.error('❌ Failed to install dependencies');
|
|
132
|
+
}
|
|
133
|
+
throw new Error('Failed to install dependencies');
|
|
138
134
|
}
|
|
139
135
|
const allNodeModulesFiles = listAllFiles(path.join(filledConfig.tempdir, 'node_modules'));
|
|
140
136
|
const seaConfigContent = {
|
|
@@ -150,66 +146,69 @@ async function nexfpack(options) {
|
|
|
150
146
|
seaConfigContent.assets[`node_modules/${relativePath}`] = file;
|
|
151
147
|
}
|
|
152
148
|
fs.writeFileSync(path.join(filledConfig.tempdir, 'sea-config.json'), JSON.stringify(seaConfigContent));
|
|
153
|
-
const launcherContent = `
|
|
154
|
-
(async () => {
|
|
155
|
-
const fs = require('fs');
|
|
156
|
-
const path = require('path');
|
|
157
|
-
const os = require('os');
|
|
158
|
-
const { pathToFileURL } = require('url');
|
|
159
|
-
let sea;
|
|
160
|
-
try {
|
|
161
|
-
sea = require('node:sea');
|
|
162
|
-
} catch (e1) {
|
|
163
|
-
try {
|
|
164
|
-
sea = process.getBuiltinModule('sea');
|
|
165
|
-
} catch (e2) {
|
|
166
|
-
try {
|
|
167
|
-
sea = globalThis.process?.getBuiltinModule?.('sea');
|
|
168
|
-
} catch (e3) {
|
|
169
|
-
sea = null;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const tempDir = path.join(os.tmpdir(), 'TEMP-NEXFPACK-' + Date.now() + '-' + Math.random().toString(36).substring(2));
|
|
175
|
-
fs.mkdirSync(tempDir, { recursive: true });
|
|
176
|
-
|
|
177
|
-
try {
|
|
178
|
-
const keys = ${JSON.stringify(Object.keys(seaConfigContent.assets).filter(key => key !== 'source.tar'))};
|
|
179
|
-
for (const key of keys) {
|
|
180
|
-
const data = sea.getRawAsset(key);
|
|
181
|
-
const filePath = path.join(tempDir, 'LANCHER', key);
|
|
182
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
183
|
-
fs.writeFileSync(filePath, Buffer.from(data));
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const tarData = sea.getRawAsset('source.tar');
|
|
187
|
-
|
|
188
|
-
const tarFile = path.join(tempDir, 'source.tar');
|
|
189
|
-
fs.writeFileSync(tarFile, Buffer.from(tarData));
|
|
190
|
-
|
|
191
|
-
const { unpackTar } = await import(pathToFileURL(path.join(tempDir, 'LANCHER', 'node_modules', 'modern-tar', 'dist', 'fs', 'index.js')));
|
|
192
|
-
const extractStream = unpackTar(tempDir);
|
|
193
|
-
const tarReadStream = fs.createReadStream(tarFile);
|
|
194
|
-
const { pipeline } = require('stream/promises');
|
|
195
|
-
await pipeline(tarReadStream, extractStream);
|
|
196
|
-
|
|
197
|
-
const entry = path.resolve(tempDir, ${JSON.stringify(filledConfig.entry)});
|
|
198
|
-
try {
|
|
199
|
-
require(entry);
|
|
200
|
-
} catch {
|
|
201
|
-
await import(pathToFileURL(entry));
|
|
202
|
-
}
|
|
203
|
-
} catch (err) {
|
|
204
|
-
console.error(err);
|
|
205
|
-
}
|
|
206
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
207
|
-
})();
|
|
149
|
+
const launcherContent = `
|
|
150
|
+
(async () => {
|
|
151
|
+
const fs = require('fs');
|
|
152
|
+
const path = require('path');
|
|
153
|
+
const os = require('os');
|
|
154
|
+
const { pathToFileURL } = require('url');
|
|
155
|
+
let sea;
|
|
156
|
+
try {
|
|
157
|
+
sea = require('node:sea');
|
|
158
|
+
} catch (e1) {
|
|
159
|
+
try {
|
|
160
|
+
sea = process.getBuiltinModule('sea');
|
|
161
|
+
} catch (e2) {
|
|
162
|
+
try {
|
|
163
|
+
sea = globalThis.process?.getBuiltinModule?.('sea');
|
|
164
|
+
} catch (e3) {
|
|
165
|
+
sea = null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const tempDir = path.join(os.tmpdir(), 'TEMP-NEXFPACK-' + Date.now() + '-' + Math.random().toString(36).substring(2));
|
|
171
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
|
172
|
+
|
|
173
|
+
try {
|
|
174
|
+
const keys = ${JSON.stringify(Object.keys(seaConfigContent.assets).filter(key => key !== 'source.tar'))};
|
|
175
|
+
for (const key of keys) {
|
|
176
|
+
const data = sea.getRawAsset(key);
|
|
177
|
+
const filePath = path.join(tempDir, 'LANCHER', key);
|
|
178
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
179
|
+
fs.writeFileSync(filePath, Buffer.from(data));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const tarData = sea.getRawAsset('source.tar');
|
|
183
|
+
|
|
184
|
+
const tarFile = path.join(tempDir, 'source.tar');
|
|
185
|
+
fs.writeFileSync(tarFile, Buffer.from(tarData));
|
|
186
|
+
|
|
187
|
+
const { unpackTar } = await import(pathToFileURL(path.join(tempDir, 'LANCHER', 'node_modules', 'modern-tar', 'dist', 'fs', 'index.js')));
|
|
188
|
+
const extractStream = unpackTar(tempDir);
|
|
189
|
+
const tarReadStream = fs.createReadStream(tarFile);
|
|
190
|
+
const { pipeline } = require('stream/promises');
|
|
191
|
+
await pipeline(tarReadStream, extractStream);
|
|
192
|
+
|
|
193
|
+
const entry = path.resolve(tempDir, ${JSON.stringify(filledConfig.entry)});
|
|
194
|
+
try {
|
|
195
|
+
require(entry);
|
|
196
|
+
} catch {
|
|
197
|
+
await import(pathToFileURL(entry));
|
|
198
|
+
}
|
|
199
|
+
} catch (err) {
|
|
200
|
+
console.error(err);
|
|
201
|
+
}
|
|
202
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
203
|
+
})();
|
|
208
204
|
`;
|
|
209
205
|
fs.writeFileSync(path.join(filledConfig.tempdir, 'launcher.cjs'), launcherContent);
|
|
210
206
|
const blobSpawnResult = child_process.spawnSync('node --experimental-sea-config sea-config.json', { stdio: 'inherit', cwd: filledConfig.tempdir, shell: true });
|
|
211
207
|
if (blobSpawnResult.status !== 0) {
|
|
212
|
-
|
|
208
|
+
if (filledConfig.log) {
|
|
209
|
+
console.error('❌ Failed to generate blob');
|
|
210
|
+
}
|
|
211
|
+
throw new Error('Failed to generate blob');
|
|
213
212
|
}
|
|
214
213
|
const NODE_SEA_FUSE = 'NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2';
|
|
215
214
|
const blobData = fs.readFileSync(path.join(filledConfig.tempdir, 'sea-prep.blob'));
|
|
@@ -230,17 +229,26 @@ async function nexfpack(options) {
|
|
|
230
229
|
console.log("⚠️ Sorry, we can't sign your executable file. Please sign it by yourself.");
|
|
231
230
|
}
|
|
232
231
|
if (filledConfig.autoDeleteTempFiles) {
|
|
233
|
-
|
|
232
|
+
if (filledConfig.log) {
|
|
233
|
+
console.log('♻️ Deleting temp files...');
|
|
234
|
+
}
|
|
234
235
|
fs.rmSync(filledConfig.tempdir, { recursive: true, force: true });
|
|
235
236
|
}
|
|
236
|
-
|
|
237
|
+
if (filledConfig.log) {
|
|
238
|
+
console.log('✅ Done!');
|
|
239
|
+
}
|
|
237
240
|
if (filledConfig.autoRun) {
|
|
238
|
-
|
|
241
|
+
if (filledConfig.log) {
|
|
242
|
+
console.log('🚀 Auto-run executable...');
|
|
243
|
+
}
|
|
239
244
|
child_process.spawnSync(exePath, { stdio: 'inherit', cwd: filledConfig.output, shell: true });
|
|
240
245
|
}
|
|
241
246
|
}
|
|
242
247
|
catch (err) {
|
|
243
|
-
|
|
248
|
+
if (filledConfig.log) {
|
|
249
|
+
console.error('❌ Nexfpack Failed:', err);
|
|
250
|
+
}
|
|
251
|
+
throw err;
|
|
244
252
|
}
|
|
245
253
|
}
|
|
246
254
|
export default nexfpack;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexfpack",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "A tool for building single executable files from Node.js scripts or modules.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "https://github.com/nexfteam/Nexfpack",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"homepage": "https://github.com/nexfteam/Nexfpack#readme",
|
|
11
11
|
"author": "nexfteam",
|
|
12
12
|
"type": "module",
|
|
13
|
+
"types": "index.d.mts",
|
|
13
14
|
"main": "index.cjs",
|
|
14
15
|
"module": "index.mjs",
|
|
15
16
|
"exports": {
|