lvyjs 0.0.2 → 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/README.md CHANGED
@@ -1,43 +1,5 @@
1
1
  # LVY
2
2
 
3
- 长春藤。 一款为 node 构建的开发工具
3
+ 一款为 node 构建的开发工具
4
4
 
5
- ```sh
6
- npm install lvyjs -D
7
- ```
8
-
9
- ```ts
10
- // lvy.config.ts
11
- import { defineConfig } from 'lvyjs'
12
- import { alias, files } from 'lvyjs/plugins'
13
- import { fileURLToPath } from 'url'
14
- import { dirname, join } from 'path'
15
- const __filename = fileURLToPath(import.meta.url)
16
- const __dirname = dirname(__filename)
17
- export default defineConfig({
18
- plugins: [
19
- {
20
- name: 'my-app',
21
- callback: () => {
22
- // 要执行的会调函数
23
- }
24
- }
25
- ],
26
- build: {
27
- plugins: [
28
- alias({
29
- entries: [{ find: '@src', replacement: join(__dirname, 'src') }]
30
- }),
31
- files({ filter: /\.(png|jpg)$/ })
32
- ]
33
- }
34
- })
35
- ```
36
-
37
- ```sh
38
- npx lvy dev
39
- ```
40
-
41
- ```sh
42
- npx lvy build
43
- ```
5
+ https://github.com/lemonade-lab/lvyjs
@@ -4,8 +4,10 @@ import typescript from '@rollup/plugin-typescript';
4
4
  import commonjs from '@rollup/plugin-commonjs';
5
5
  import json from '@rollup/plugin-json';
6
6
  import styles from 'rollup-plugin-styles';
7
- import { runRollupStylesCSSImport } from '../plugins/loader-css.js';
8
7
  import { getFiles } from './get-files.js';
8
+ import alias from '@rollup/plugin-alias';
9
+ import { rollupStylesCSSImport } from '../plugins/loader-css.js';
10
+ import { rollupAssets } from '../plugins/loader-files.js';
9
11
 
10
12
  /**
11
13
  * 用于忽略警告
@@ -18,38 +20,103 @@ const onwarn = (warning, warn) => {
18
20
  warn(warning);
19
21
  };
20
22
  /**
21
- *
23
+ * 打包 JS
24
+ * *** 注意 **
25
+ * 和initConfig配合使用
26
+ * **
27
+ * 确保已经初始化了配置
22
28
  * @param inputs
23
29
  * @param output
24
30
  */
25
- const buildJs = async (inputs, output) => {
26
- // 从全局变量中,拿到 rollup 的配置
27
- const plguins = [];
28
- // 存在build配置
29
- if (global?.lvyConfig?.build) {
30
- const p = global.lvyConfig.build?.plugins;
31
- if (p && Array.isArray(p)) {
32
- // 遍历插件
33
- const ps = p.filter(item => item.belong == 'rollup');
34
- for (const item of ps) {
35
- plguins.push(item.load());
31
+ const buildJS = async (inputs, output) => {
32
+ if (!global.lvyConfig)
33
+ global.lvyConfig = {};
34
+ if (!global.lvyConfig.build)
35
+ global.lvyConfig.build = {};
36
+ // 插件
37
+ const plugins = [];
38
+ for (const key in global.lvyConfig.build) {
39
+ if (typeof global.lvyConfig.build[key] == 'boolean') {
40
+ continue;
41
+ }
42
+ if (key === 'alias' && !global.lvyConfig.build['@rollup/plugin-alias']) {
43
+ plugins.push(alias(global.lvyConfig.build[key]));
44
+ }
45
+ else if (key === 'assets') {
46
+ plugins.push(rollupAssets(global.lvyConfig.build[key]));
47
+ }
48
+ else if (key === 'styles') {
49
+ plugins.push(styles({
50
+ mode: ['inject', () => '']
51
+ }));
52
+ plugins.push(rollupStylesCSSImport(global.lvyConfig.build[key]));
53
+ }
54
+ else if (key === 'commonjs' && !global.lvyConfig.build['@rollup/plugin-commonjs']) {
55
+ plugins.push(commonjs(global.lvyConfig.build[key]));
56
+ }
57
+ else if (key === 'json' && !global.lvyConfig.build['@rollup/plugin-json']) {
58
+ plugins.push(json(global.lvyConfig.build[key]));
59
+ }
60
+ else if (key === 'typescript' && !global.lvyConfig.build['@rollup/plugin-typescript']) {
61
+ plugins.push(typescript(global.lvyConfig.build[key]));
62
+ }
63
+ else if (key === 'plugins') {
64
+ if (Array.isArray(global.lvyConfig.build[key])) {
65
+ for (const plugin of global.lvyConfig.build[key]) {
66
+ plugins.push(plugin);
67
+ }
36
68
  }
37
69
  }
70
+ else {
71
+ const plugin = (await import(key)).default;
72
+ plugins.push(plugin(global.lvyConfig.build[key]));
73
+ }
38
74
  }
39
- const bundle = await rollup({
40
- input: inputs,
41
- plugins: [
42
- ...plguins,
43
- styles({
75
+ // 如果不存在这些配置
76
+ const keys = ['assets', 'styles', 'commonjs', 'json', 'typescript'];
77
+ for (const key of keys) {
78
+ // 如果是布尔值
79
+ if (typeof global.lvyConfig.build[key] == 'boolean') {
80
+ continue;
81
+ }
82
+ // 存在这些配置
83
+ if (global.lvyConfig.build[key]) {
84
+ continue;
85
+ }
86
+ //
87
+ if (key == 'assets') {
88
+ plugins.push(rollupAssets());
89
+ }
90
+ else if (key == 'styles') {
91
+ plugins.push(styles({
44
92
  mode: ['inject', () => '']
45
- }),
46
- runRollupStylesCSSImport(),
47
- commonjs(),
48
- json(),
49
- typescript()
50
- ],
51
- onwarn: onwarn
52
- });
93
+ }));
94
+ plugins.push(rollupStylesCSSImport());
95
+ }
96
+ else if (key === 'commonjs') {
97
+ plugins.push(commonjs());
98
+ }
99
+ else if (key === 'json') {
100
+ plugins.push(json());
101
+ }
102
+ else if (key === 'typescript') {
103
+ plugins.push(typescript());
104
+ }
105
+ else if (key === 'plugins') {
106
+ plugins.push(alias());
107
+ }
108
+ }
109
+ // rollup 配置
110
+ const Options = global.lvyConfig.build?.rollupOptions ?? {};
111
+ // rollup 配置
112
+ const rollupOptions = {
113
+ input: inputs,
114
+ plugins: plugins,
115
+ onwarn: onwarn,
116
+ ...Options
117
+ };
118
+ // build
119
+ const bundle = await rollup(rollupOptions);
53
120
  // 写入输出文件
54
121
  await bundle.write({
55
122
  dir: output,
@@ -64,7 +131,7 @@ const buildJs = async (inputs, output) => {
64
131
  */
65
132
  async function buildAndRun(input, output) {
66
133
  const inputFiles = getFiles(join(process.cwd(), input));
67
- await buildJs(inputFiles, output);
134
+ await buildJS(inputFiles, output);
68
135
  }
69
136
 
70
- export { buildAndRun };
137
+ export { buildAndRun, buildJS };
package/lib/index.d.ts CHANGED
@@ -1 +1 @@
1
- export { defineConfig } from './store.js';
1
+ export { defineConfig, initConfig } from './store.js';
package/lib/index.js CHANGED
@@ -1,46 +1,50 @@
1
- import { buildAndRun } from './build/rullup.js'
2
- import { initConfig } from './store.js'
3
- export { defineConfig } from './store.js'
1
+ import { buildAndRun } from './build/rullup.js';
2
+ import { initConfig } from './store.js';
3
+ export { defineConfig } from './store.js';
4
4
 
5
5
  /**
6
6
  * @param input
7
7
  */
8
8
  const onDev = async () => {
9
- const apps = []
10
- // 修改config
11
- for (const plugin of global.lvyConfig.plugins) {
12
- if (plugin?.config) {
13
- const cfg = await plugin.config(global.lvyConfig)
14
- global.lvyConfig = {
15
- ...global.lvyConfig,
16
- ...cfg
17
- }
9
+ // 修改config
10
+ for (const plugin of global.lvyConfig.plugins) {
11
+ if (plugin?.config) {
12
+ const cfg = await plugin.config(global.lvyConfig);
13
+ for (const key in cfg) {
14
+ // 不能覆盖plugins
15
+ if (cfg[key] != 'plugins') {
16
+ // 覆盖
17
+ global.lvyConfig[key] = cfg[key];
18
+ }
19
+ }
20
+ }
18
21
  }
19
- apps.push(plugin)
20
- }
21
- // 执行loader
22
- await import('./loader/main.js')
23
- // 执行callback
24
- for (const app of apps) {
25
- if (app?.callback) await app.callback()
26
- }
27
- }
22
+ // 执行loader
23
+ await import('./loader/main.js');
24
+ // 执行 useApp
25
+ for (const plugin of global.lvyConfig.plugins) {
26
+ if (plugin?.useApp)
27
+ await plugin.useApp();
28
+ }
29
+ };
28
30
  /**
29
31
  *
30
32
  * @param input
31
33
  * @param ouput
32
34
  */
33
35
  const onBuild = () => {
34
- buildAndRun('src', 'lib')
35
- }
36
-
36
+ buildAndRun('src', 'lib');
37
+ };
37
38
  const main = async () => {
38
- if (process.argv.includes('--lvy-dev')) {
39
- await initConfig()
40
- onDev()
41
- } else if (process.argv.includes('--lvy-build')) {
42
- await initConfig()
43
- onBuild()
44
- }
45
- }
46
- main()
39
+ if (process.argv.includes('--lvy-dev')) {
40
+ await initConfig();
41
+ onDev();
42
+ }
43
+ else if (process.argv.includes('--lvy-build')) {
44
+ await initConfig();
45
+ onBuild();
46
+ }
47
+ };
48
+ main();
49
+
50
+ export { initConfig };
@@ -1,214 +1,36 @@
1
- import { resolve, relative, dirname, join } from 'path';
2
- import { existsSync, readFileSync } from 'fs';
3
- import { spawn } from 'child_process';
4
1
  import esbuild from 'esbuild';
5
- import crypto from 'node:crypto';
2
+ import { esBuildAsstes, esBuildCSS } from './plugins.js';
6
3
 
7
- let tsconfig = null;
8
- let aliases = {};
9
- const assetsReg = /\.(png|jpg|jpeg|gif|svg|webp|ico)$/;
10
- const cssReg = /\.(css|scss)$/;
11
- // 初始化函数,读取并解析 tsconfig.json 文件
12
- const init = () => {
13
- try {
14
- const tsconfigPath = resolve(process.cwd(), 'tsconfig.json');
15
- if (existsSync(tsconfigPath)) {
16
- const tsconfigContent = readFileSync(tsconfigPath, 'utf-8');
17
- tsconfig = JSON.parse(tsconfigContent);
18
- aliases = tsconfig.compilerOptions?.paths || {};
19
- }
20
- else {
21
- tsconfig = 'error';
22
- }
23
- }
24
- catch {
25
- tsconfig = 'error';
26
- }
27
- };
28
- // 初始化配置
29
- init();
30
- /**
31
- *
32
- * @param input
33
- * @param output
34
- */
35
- const startCssPost = (input, output) => {
36
- const run = ['postcss', input, '-o', output, '--watch'];
37
- // 启动 Tailwind 进程
38
- const cssPostProcess = spawn('npx', run, {
39
- stdio: 'inherit',
40
- shell: process.platform === 'win32'
41
- });
42
- cssPostProcess.on('error', err => {
43
- console.error('Failed to start Tailwind process:', err);
44
- });
45
- };
46
- /**
47
- * 生成模块内容
48
- * @param {string} relativePath 相对路径
49
- */
50
- const generateModuleContent = (relativePath) => {
51
- const contents = [
52
- 'const createUrl = (basePath, path) => {',
53
- "const platform = ['linux', 'android', 'darwin'];",
54
- 'const T = platform.includes(process.platform);',
55
- 'const reg = T ? /^file:\\/\\// : /^file:\\/\\/\\//;',
56
- "return new URL(path, basePath).href.replace(reg, '');",
57
- '};',
58
- `const fileUrl = createUrl(import.meta.url, '${relativePath}');`,
59
- 'export default fileUrl;'
60
- ].join('\n');
61
- return contents;
62
- };
63
- const chache = {};
64
- const getHash = (str) => {
65
- // 使用 MD5 算法创建哈希对象
66
- const hash = crypto.createHash('md5');
67
- // 更新哈希对象内容
68
- hash.update(str);
69
- return hash.digest('hex');
70
- };
4
+ // 插件
5
+ const plugins = [];
71
6
  /**
72
7
  *
73
- * @param inputPath
74
- * @returns
75
8
  */
76
- const convertPath = (inputPath) => {
77
- return process.platform === 'win32' ? inputPath.replace(/\\/g, '/') : inputPath;
78
- };
79
- const handleAsstesFile = (url) => {
80
- for (const alias in aliases) {
81
- const aliasPattern = alias.replace('/*', '');
82
- if (url.startsWith(aliasPattern)) {
83
- const aliasPaths = aliases[alias];
84
- for (const aliasPath of aliasPaths) {
85
- const fileUrl = join(process.cwd(), aliasPath.replace('/*', ''), url.replace(aliasPattern, ''));
86
- return `export default "${convertPath(fileUrl)}";`;
87
- }
9
+ const initPlugins = async () => {
10
+ for (const key in global.lvyConfig.esbuild) {
11
+ if (typeof global.lvyConfig.esbuild[key] == 'boolean') {
12
+ continue;
88
13
  }
89
14
  }
90
- return null;
91
- };
92
- /**
93
- *
94
- * @param param0
95
- */
96
- const esBuildAsstesFule = () => {
97
- const index = process.argv.indexOf('--import-assets');
98
- const filter = index != -1 ? new RegExp(process.argv[index + 1]) : assetsReg;
99
- const namespace = 'assets';
100
- return {
101
- name: 'file-loader',
102
- setup(build) {
103
- const outputDirs = new Map();
104
- // 过滤图片文件
105
- build.onResolve({ filter }, args => {
106
- const dir = resolve(args.resolveDir, args.path);
107
- outputDirs.set(dir, args.importer);
108
- return {
109
- path: dir,
110
- namespace
111
- };
112
- });
113
- build.onLoad({ filter, namespace }, async (args) => {
114
- if (!outputDirs.has(args.path))
115
- return null;
116
- const outputDir = outputDirs.get(args.path);
117
- const relativePath = relative(dirname(outputDir), args.path);
118
- // 不管是别名资源。都只是需要返回一个路径
119
- const aliasResult = handleAsstesFile(relativePath);
120
- if (aliasResult) {
121
- return {
122
- contents: aliasResult,
123
- loader: 'js'
124
- };
125
- }
126
- return {
127
- contents: generateModuleContent(relativePath),
128
- loader: 'js'
129
- };
130
- });
15
+ // 如果不存在这些配置
16
+ const keys = ['assets', 'styles'];
17
+ for (const key of keys) {
18
+ // 如果是布尔值
19
+ if (typeof global.lvyConfig.esbuild[key] == 'boolean') {
20
+ continue;
131
21
  }
132
- };
133
- };
134
- /**
135
- *
136
- * @param fileUrl
137
- * @returns
138
- */
139
- const handleCSS = (fileUrl) => {
140
- const hash = getHash(fileUrl);
141
- const outputDir = join(process.cwd(), 'node_modules', 'alemonjs', 'assets', `${hash}.css`);
142
- if (!chache[fileUrl]) {
143
- startCssPost(fileUrl, outputDir);
144
- chache[fileUrl] = true;
145
- }
146
- return outputDir;
147
- };
148
- /**
149
- * 处理路径别名的加载
150
- * @param {string} url URL
151
- * @returns {object|null} 加载结果
152
- */
153
- const handleCSSPath = (url) => {
154
- for (const alias in aliases) {
155
- const aliasPattern = alias.replace('/*', '');
156
- if (url.startsWith(aliasPattern)) {
157
- const aliasPaths = aliases[alias];
158
- for (const aliasPath of aliasPaths) {
159
- const fileUrl = join(process.cwd(), aliasPath.replace('/*', ''), url.replace(aliasPattern, ''));
160
- const outputDir = handleCSS(fileUrl);
161
- return `export default "${convertPath(outputDir)}";`;
162
- }
22
+ // 存在这些配置
23
+ if (global.lvyConfig.esbuild[key]) {
24
+ continue;
163
25
  }
164
- }
165
- return null;
166
- };
167
- /**
168
- * css资源处理插件
169
- * @param param0
170
- * @returns
171
- */
172
- const esBuildCSS = () => {
173
- const index = process.argv.indexOf('--import-css');
174
- const filter = index != -1 ? new RegExp(process.argv[index + 1]) : cssReg;
175
- const namespace = 'css';
176
- return {
177
- name: 'css-loader',
178
- setup(build) {
179
- const outputDirs = new Map();
180
- // 过滤 CSS/SCSS 文件
181
- build.onResolve({ filter }, args => {
182
- const dir = resolve(args.resolveDir, args.path);
183
- outputDirs.set(dir, args.importer);
184
- return {
185
- path: dir,
186
- namespace
187
- };
188
- });
189
- // 加载 CSS/SCSS 文件
190
- build.onLoad({ filter, namespace }, async (args) => {
191
- if (!outputDirs.has(args.path))
192
- return null;
193
- const outputDir = outputDirs.get(args.path);
194
- // 计算相对路径
195
- const relativePath = relative(dirname(outputDir), args.path);
196
- // 处理路径别名的加载
197
- const aliasResult = handleCSSPath(relativePath);
198
- if (aliasResult) {
199
- return {
200
- contents: aliasResult,
201
- loader: 'js'
202
- };
203
- }
204
- // 不是别名资源
205
- return {
206
- contents: `export default "${convertPath(handleCSS(args.path))}";`,
207
- loader: 'js'
208
- };
209
- });
26
+ //
27
+ if (key == 'assets') {
28
+ plugins.push(esBuildAsstes());
29
+ }
30
+ else if (key === 'styles') {
31
+ plugins.push(esBuildCSS());
210
32
  }
211
- };
33
+ }
212
34
  };
213
35
  /**
214
36
  *
@@ -216,23 +38,37 @@ const esBuildCSS = () => {
216
38
  * @returns
217
39
  */
218
40
  const ESBuild = async (input) => {
219
- const plugins = [];
220
- if (!process.arch.includes('--no-import-css')) {
221
- plugins.push(esBuildCSS());
222
- }
223
- if (!process.arch.includes('--no-import-assets')) {
224
- plugins.push(esBuildAsstesFule());
41
+ // 如果没有配置
42
+ if (!global.lvyConfig)
43
+ global.lvyConfig = {};
44
+ if (!global.lvyConfig.esbuild)
45
+ global.lvyConfig.esbuild = {};
46
+ // 如果没有插件
47
+ if (plugins.length === 0) {
48
+ // init plugisn
49
+ await initPlugins();
225
50
  }
51
+ //
52
+ const options = global.lvyConfig.esbuild?.options || {};
53
+ // 构建
226
54
  const result = await esbuild.build({
55
+ // 入口文件
227
56
  entryPoints: [input],
57
+ //
228
58
  bundle: true,
59
+ // 平台
229
60
  platform: 'node',
61
+ // 输出格式
230
62
  format: 'esm',
63
+ // 不写入文件
231
64
  write: false,
232
65
  plugins,
233
- external: ['*']
66
+ // 忽略所有外部依赖
67
+ external: ['*'],
68
+ ...options
234
69
  });
70
+ // 返回结果
235
71
  return result.outputFiles.map(file => new TextDecoder().decode(file.contents)).join('\n');
236
72
  };
237
73
 
238
- export { ESBuild, esBuildAsstesFule, esBuildCSS };
74
+ export { ESBuild };
@@ -20,11 +20,10 @@ const load = async (url, context, defaultLoad) => {
20
20
  return defaultLoad(url, context);
21
21
  }
22
22
  const code = await ESBuild(url.replace(reg, ''));
23
- return {
23
+ return defaultLoad(url, {
24
24
  format: 'module',
25
- source: code,
26
- shortCircuit: true
27
- };
25
+ source: code
26
+ });
28
27
  };
29
28
 
30
29
  export { load };
@@ -0,0 +1,10 @@
1
+ type ESBuildAsstesOptions = {
2
+ filter?: RegExp;
3
+ namespace?: string;
4
+ };
5
+ type ESBuildCSSOptions = {
6
+ filter?: RegExp;
7
+ namespace?: string;
8
+ };
9
+
10
+ export type { ESBuildAsstesOptions, ESBuildCSSOptions };
@@ -0,0 +1,218 @@
1
+ import { resolve, relative, dirname, join } from 'path';
2
+ import { existsSync, readFileSync } from 'fs';
3
+ import { spawn } from 'child_process';
4
+ import crypto from 'node:crypto';
5
+ import JSON5 from 'json5';
6
+
7
+ let tsconfig = null;
8
+ let aliases = {};
9
+ const assetsReg = /\.(png|jpg|jpeg|gif|svg|webp|ico)$/;
10
+ const cssReg = /\.(css|scss)$/;
11
+ // 初始化函数,读取并解析 tsconfig.json 文件
12
+ const init = () => {
13
+ try {
14
+ const tsconfigPath = resolve(process.cwd(), 'tsconfig.json');
15
+ if (existsSync(tsconfigPath)) {
16
+ const tsconfigContent = readFileSync(tsconfigPath, 'utf-8');
17
+ tsconfig = JSON5.parse(tsconfigContent);
18
+ aliases = tsconfig.compilerOptions?.paths || {};
19
+ }
20
+ else {
21
+ tsconfig = 'error';
22
+ }
23
+ }
24
+ catch {
25
+ tsconfig = 'error';
26
+ }
27
+ };
28
+ // 初始化配置
29
+ init();
30
+ /**
31
+ *
32
+ * @param input
33
+ * @param output
34
+ */
35
+ const startCssPost = (input, output) => {
36
+ const run = ['postcss', input, '-o', output, '--watch'];
37
+ // 启动 Tailwind 进程
38
+ const cssPostProcess = spawn('npx', run, {
39
+ stdio: 'inherit',
40
+ shell: process.platform === 'win32'
41
+ });
42
+ cssPostProcess.on('error', err => {
43
+ console.error('Failed to start Tailwind process:', err);
44
+ });
45
+ process.on('exit', () => {
46
+ cssPostProcess.kill();
47
+ });
48
+ };
49
+ /**
50
+ * 生成模块内容
51
+ * @param {string} relativePath 相对路径
52
+ */
53
+ const generateModuleContent = (relativePath) => {
54
+ const contents = [
55
+ 'const createUrl = (basePath, path) => {',
56
+ "const platform = ['linux', 'android', 'darwin'];",
57
+ 'const T = platform.includes(process.platform);',
58
+ 'const reg = T ? /^file:\\/\\// : /^file:\\/\\/\\//;',
59
+ "return new URL(path, basePath).href.replace(reg, '');",
60
+ '};',
61
+ `const fileUrl = createUrl(import.meta.url, '${relativePath}');`,
62
+ 'export default fileUrl;'
63
+ ].join('\n');
64
+ return contents;
65
+ };
66
+ const chache = {};
67
+ const getHash = (str) => {
68
+ // 使用 MD5 算法创建哈希对象
69
+ const hash = crypto.createHash('md5');
70
+ // 更新哈希对象内容
71
+ hash.update(str);
72
+ return hash.digest('hex');
73
+ };
74
+ /**
75
+ *
76
+ * @param inputPath
77
+ * @returns
78
+ */
79
+ const convertPath = (inputPath) => {
80
+ return process.platform === 'win32' ? inputPath.replace(/\\/g, '/') : inputPath;
81
+ };
82
+ const handleAsstesFile = (url) => {
83
+ for (const alias in aliases) {
84
+ const aliasPattern = alias.replace('/*', '');
85
+ if (url.startsWith(aliasPattern)) {
86
+ const aliasPaths = aliases[alias];
87
+ for (const aliasPath of aliasPaths) {
88
+ const fileUrl = join(process.cwd(), aliasPath.replace('/*', ''), url.replace(aliasPattern, ''));
89
+ return `export default "${convertPath(fileUrl)}";`;
90
+ }
91
+ }
92
+ }
93
+ return null;
94
+ };
95
+ /**
96
+ *
97
+ * @param fileUrl
98
+ * @returns
99
+ */
100
+ const handleCSS = (fileUrl) => {
101
+ const hash = getHash(fileUrl);
102
+ const outputDir = join(process.cwd(), 'node_modules', 'lvyjs', 'assets', `${hash}.css`);
103
+ if (!chache[fileUrl]) {
104
+ startCssPost(fileUrl, outputDir);
105
+ chache[fileUrl] = true;
106
+ }
107
+ return outputDir;
108
+ };
109
+ /**
110
+ * 处理路径别名的加载
111
+ * @param {string} url URL
112
+ * @returns {object|null} 加载结果
113
+ */
114
+ const handleCSSPath = (url) => {
115
+ for (const alias in aliases) {
116
+ const aliasPattern = alias.replace('/*', '');
117
+ if (url.startsWith(aliasPattern)) {
118
+ const aliasPaths = aliases[alias];
119
+ for (const aliasPath of aliasPaths) {
120
+ const fileUrl = join(process.cwd(), aliasPath.replace('/*', ''), url.replace(aliasPattern, ''));
121
+ const outputDir = handleCSS(fileUrl);
122
+ return `export default "${convertPath(outputDir)}";`;
123
+ }
124
+ }
125
+ }
126
+ return null;
127
+ };
128
+ /**
129
+ *
130
+ * @param param0
131
+ */
132
+ const esBuildAsstes = (optoins = {}) => {
133
+ // 默认配置
134
+ const filter = optoins?.filter ?? assetsReg;
135
+ const namespace = optoins?.namespace ?? 'assets';
136
+ // 返回插件
137
+ return {
138
+ name: 'assets-loader',
139
+ setup(build) {
140
+ const outputDirs = new Map();
141
+ // 过滤图片文件
142
+ build.onResolve({ filter }, args => {
143
+ const dir = resolve(args.resolveDir, args.path);
144
+ outputDirs.set(dir, args.importer);
145
+ return {
146
+ path: dir,
147
+ namespace
148
+ };
149
+ });
150
+ build.onLoad({ filter, namespace }, async (args) => {
151
+ if (!outputDirs.has(args.path))
152
+ return null;
153
+ const outputDir = outputDirs.get(args.path);
154
+ const relativePath = relative(dirname(outputDir), args.path);
155
+ // 不管是别名资源。都只是需要返回一个路径
156
+ const aliasResult = handleAsstesFile(relativePath);
157
+ if (aliasResult) {
158
+ return {
159
+ contents: aliasResult,
160
+ loader: 'js'
161
+ };
162
+ }
163
+ return {
164
+ contents: generateModuleContent(relativePath),
165
+ loader: 'js'
166
+ };
167
+ });
168
+ }
169
+ };
170
+ };
171
+ /**
172
+ * css资源处理插件
173
+ * @param param0
174
+ * @returns
175
+ */
176
+ const esBuildCSS = (optoins = {}) => {
177
+ const filter = optoins?.filter || cssReg;
178
+ const namespace = optoins?.namespace || 'css';
179
+ // 返回插件
180
+ return {
181
+ name: 'css-loader',
182
+ setup(build) {
183
+ const outputDirs = new Map();
184
+ // 过滤 CSS/SCSS 文件
185
+ build.onResolve({ filter }, args => {
186
+ const dir = resolve(args.resolveDir, args.path);
187
+ outputDirs.set(dir, args.importer);
188
+ return {
189
+ path: dir,
190
+ namespace
191
+ };
192
+ });
193
+ // 加载 CSS/SCSS 文件
194
+ build.onLoad({ filter, namespace }, async (args) => {
195
+ if (!outputDirs.has(args.path))
196
+ return null;
197
+ const outputDir = outputDirs.get(args.path);
198
+ // 计算相对路径
199
+ const relativePath = relative(dirname(outputDir), args.path);
200
+ // 处理路径别名的加载
201
+ const aliasResult = handleCSSPath(relativePath);
202
+ if (aliasResult) {
203
+ return {
204
+ contents: aliasResult,
205
+ loader: 'js'
206
+ };
207
+ }
208
+ // 不是别名资源
209
+ return {
210
+ contents: `export default "${convertPath(handleCSS(args.path))}";`,
211
+ loader: 'js'
212
+ };
213
+ });
214
+ }
215
+ };
216
+ };
217
+
218
+ export { esBuildAsstes, esBuildCSS };
@@ -1,27 +1,2 @@
1
- import * as rollup from 'rollup';
2
- import { RollupAliasOptions } from '@rollup/plugin-alias';
3
-
4
- /**
5
- * ruleup别名插件
6
- * @param options
7
- * @returns
8
- */
9
- declare const alias: (options?: RollupAliasOptions) => {
10
- belong: "rollup" | "esbuild" | "other";
11
- name: string;
12
- load: () => rollup.Plugin<any>;
13
- };
14
- /**
15
- * ruleup插件:对指定类型文件进行字符串引用处理
16
- * @param options
17
- * @returns
18
- */
19
- declare const files: (options: {
20
- filter: RegExp;
21
- }) => {
22
- belong: "rollup" | "esbuild" | "other";
23
- name: string;
24
- load: () => rollup.InputPluginOption;
25
- };
26
-
27
- export { alias, files };
1
+ export { RollupStylesCSSImportOptions, rollupStylesCSSImport } from './loader-css.js';
2
+ export { RollupAssetsOptions, rollupAssets } from './loader-files.js';
@@ -1,29 +1,2 @@
1
- import aliasx from '@rollup/plugin-alias';
2
- import { rollupNodeFiles } from './loader-files.js';
3
-
4
- /**
5
- * ruleup别名插件
6
- * @param options
7
- * @returns
8
- */
9
- const alias = (options) => {
10
- return {
11
- belong: 'rollup',
12
- name: 'alias',
13
- load: () => aliasx(options)
14
- };
15
- };
16
- /**
17
- * ruleup插件:对指定类型文件进行字符串引用处理
18
- * @param options
19
- * @returns
20
- */
21
- const files = (options) => {
22
- return {
23
- belong: 'rollup',
24
- name: 'import-files',
25
- load: () => rollupNodeFiles(options)
26
- };
27
- };
28
-
29
- export { alias, files };
1
+ export { rollupStylesCSSImport } from './loader-css.js';
2
+ export { rollupAssets } from './loader-files.js';
@@ -0,0 +1,12 @@
1
+ import { InputPluginOption } from 'rollup';
2
+
3
+ type RollupStylesCSSImportOptions = {
4
+ include?: RegExp;
5
+ };
6
+ /**
7
+ *
8
+ * @returns
9
+ */
10
+ declare const rollupStylesCSSImport: ({ include }?: RollupStylesCSSImportOptions) => InputPluginOption;
11
+
12
+ export { type RollupStylesCSSImportOptions, rollupStylesCSSImport };
@@ -5,8 +5,7 @@ import { resolve, dirname, basename } from 'node:path';
5
5
  *
6
6
  * @returns
7
7
  */
8
- const runRollupStylesCSSImport = () => {
9
- const { include = /\.(css|scss)$/i } = {};
8
+ const rollupStylesCSSImport = ({ include = /\.(css|scss)$/i } = {}) => {
10
9
  const filter = createFilter(include, null);
11
10
  return {
12
11
  name: 'c-css',
@@ -56,4 +55,4 @@ const runRollupStylesCSSImport = () => {
56
55
  };
57
56
  };
58
57
 
59
- export { runRollupStylesCSSImport };
58
+ export { rollupStylesCSSImport };
@@ -0,0 +1,12 @@
1
+ import { InputPluginOption } from 'rollup';
2
+
3
+ type RollupAssetsOptions = {
4
+ filter?: RegExp;
5
+ };
6
+ /**
7
+ * @param {Object} options
8
+ * @returns {Object}
9
+ */
10
+ declare const rollupAssets: ({ filter }?: RollupAssetsOptions) => InputPluginOption;
11
+
12
+ export { type RollupAssetsOptions, rollupAssets };
@@ -5,7 +5,7 @@ import { readFileSync } from 'fs';
5
5
  * @param {Object} options
6
6
  * @returns {Object}
7
7
  */
8
- const rollupNodeFiles = ({ filter }) => {
8
+ const rollupAssets = ({ filter = /\.(png|jpg|jpeg|gif|svg|webp|ico)$/ } = {}) => {
9
9
  return {
10
10
  name: 'rollup-node-files',
11
11
  resolveId(source, importer) {
@@ -35,4 +35,4 @@ const rollupNodeFiles = ({ filter }) => {
35
35
  };
36
36
  };
37
37
 
38
- export { rollupNodeFiles };
38
+ export { rollupAssets };
package/lib/store.d.ts CHANGED
@@ -1,40 +1,106 @@
1
- import { RollupOptions } from 'rollup'
1
+ import { RollupAliasOptions } from '@rollup/plugin-alias';
2
+ import { RollupOptions } from 'rollup';
3
+ import { RollupStylesCSSImportOptions } from './plugins/loader-css.js';
4
+ import { RollupCommonJSOptions } from '@rollup/plugin-commonjs';
5
+ import { RollupJsonOptions } from '@rollup/plugin-json';
6
+ import { RollupTypescriptOptions } from '@rollup/plugin-typescript';
7
+ import { SameShape, BuildOptions } from 'esbuild';
8
+ import { RollupAssetsOptions } from './plugins/loader-files.js';
9
+ import { ESBuildAsstesOptions, ESBuildCSSOptions } from './loader/plugins.js';
2
10
 
3
11
  type Options = {
4
- plugins?: {
5
- name: string
6
12
  /**
7
- * ⚠️直接optoins进行调整
8
- * @param options
9
- * @returns
13
+ * 配置调整机及其回调插件
10
14
  */
11
- config?: (options: Options) => Options
15
+ plugins?: {
16
+ /**
17
+ * 应用名
18
+ */
19
+ name: string;
20
+ /**
21
+ * ⚠️直接optoins进行调整
22
+ * @param options
23
+ * @returns
24
+ */
25
+ config?: (options: Options) => Options;
26
+ /**
27
+ * 执行
28
+ */
29
+ useApp?: () => void;
30
+ }[];
12
31
  /**
13
- * 执行
32
+ * 运行时配置
14
33
  */
15
- callback?: () => void
16
- }[]
17
- build?: {
18
- plugins?: {
19
- belong: 'rollup' | 'esbuild' | 'other'
20
- name: string
21
- load: any
22
- }[]
23
- rollupOptions?: {
24
- input?: string | string[]
25
- } & RollupOptions
26
- }
27
- }
34
+ esbuild?: {
35
+ [key: string]: any;
36
+ /**
37
+ * 资源
38
+ */
39
+ assets?: ESBuildAsstesOptions | false;
40
+ /**
41
+ * 样式处理
42
+ */
43
+ styles?: ESBuildCSSOptions | false;
44
+ /**
45
+ * ⚠️ 直接覆盖esbuild配置
46
+ */
47
+ options?: SameShape<BuildOptions, BuildOptions>;
48
+ };
49
+ /**
50
+ * 打包时配置
51
+ */
52
+ build?: {
53
+ [key: string]: any;
54
+ /**
55
+ * 别名
56
+ */
57
+ alias?: RollupAliasOptions | false;
58
+ /**
59
+ * 文件过滤
60
+ */
61
+ assets?: RollupAssetsOptions | false;
62
+ /**
63
+ * 样式处理配置
64
+ */
65
+ styles?: RollupStylesCSSImportOptions | false;
66
+ /**
67
+ * cjs文件处理
68
+ */
69
+ commonjs?: RollupCommonJSOptions | false;
70
+ /**
71
+ * josn文件处理
72
+ */
73
+ json?: RollupJsonOptions | false;
74
+ /**
75
+ * ts配置
76
+ */
77
+ typescript?: RollupTypescriptOptions | false;
78
+ /**
79
+ *
80
+ */
81
+ plugins?: any[];
82
+ /**
83
+ * ⚠️ 直接覆盖build配置
84
+ */
85
+ rollupOptions?: {
86
+ input?: string | string[];
87
+ } & RollupOptions;
88
+ };
89
+ };
28
90
  /**
29
91
  *
30
92
  */
31
93
  declare global {
32
- var lvyConfig: Options
94
+ var lvyConfig: Options;
33
95
  }
96
+ /**
97
+ *
98
+ */
99
+ declare const initConfig: () => Promise<void>;
34
100
  /**
35
101
  * @param param0
36
102
  * @returns
37
103
  */
38
- declare const defineConfig: (optoins?: Options) => Options
104
+ declare const defineConfig: (optoins?: Options) => Options;
39
105
 
40
- export { type Options, defineConfig }
106
+ export { type Options, defineConfig, initConfig };
package/lib/store.js CHANGED
@@ -5,10 +5,8 @@ import { join } from 'path';
5
5
  *
6
6
  */
7
7
  const initConfig = async () => {
8
- if (!global.lvyConfig) {
9
- // init
8
+ if (!global.lvyConfig)
10
9
  global.lvyConfig = {};
11
- }
12
10
  const files = [
13
11
  'lvy.config.ts',
14
12
  'lvy.config.js',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lvyjs",
3
- "version": "0.0.2",
3
+ "version": "0.1.0",
4
4
  "description": "tsx compile script",
5
5
  "author": "lemonade",
6
6
  "license": "MIT",
@@ -26,6 +26,7 @@
26
26
  "postcss-styled": "^0.34.0",
27
27
  "postcss-syntax": "^0.36.2",
28
28
  "postcss-url": "^10.1.3",
29
+ "json5": "^2.2.3",
29
30
  "rollup": "^4.18.1",
30
31
  "rollup-plugin-dts": "^6.1.1",
31
32
  "rollup-plugin-styles": "^4.0.0",
@@ -51,10 +52,6 @@
51
52
  "./env": {
52
53
  "types": "./env.d.ts"
53
54
  },
54
- "./plugins": {
55
- "import": "./lib/plugins/index.js",
56
- "types": "./lib/plugins/index.d.ts"
57
- },
58
55
  "./tsconfig.json": {
59
56
  "import": "./tsconfig.json",
60
57
  "types": "./tsconfig.json"
@@ -72,9 +69,9 @@
72
69
  "registry": "https://registry.npmjs.org",
73
70
  "access": "public"
74
71
  },
75
- "bugs": "https://github.com/ningmengchongshui/alemonjs/issues",
72
+ "bugs": "https://github.com/lemonade-lab/lvy/issues",
76
73
  "repository": {
77
74
  "type": "git",
78
- "url": "https://github.com/ningmengchongshui/alemonjs.git"
75
+ "url": "https://github.com/lemonade-lab/lvy.git"
79
76
  }
80
77
  }