mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-08 10:56:15 -08:00
refactor: update import statements to use node built-in modules
chore: update lerna configuration formatting chore: bump version in package.json to 6.0.0 fix: modify build scripts for improved readability and consistency feat: enhance translation scripts with better error handling and progress tracking chore: improve plugin creation script for better user experience style: format svgo configuration for consistency
This commit is contained in:
1 parent
3540cd0cce
commit
fa755b5f61
11 files changed
+509
-496
No files matched your search
+3
-3
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"packages": ["packages/*"],
|
||||
"version": "independent",
|
||||
"npmClient": "yarn"
|
||||
"packages": ["packages/*"],
|
||||
"version": "independent",
|
||||
"npmClient": "yarn"
|
||||
}
|
||||
+5
-6
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "artplayer-packages",
|
||||
"type": "module",
|
||||
"version": "5.2.0",
|
||||
"version": "6.0.0",
|
||||
"private": true,
|
||||
"description": "ArtPlayer.js is a modern and full featured HTML5 video player",
|
||||
"workspaces": [
|
||||
@@ -25,17 +25,17 @@
|
||||
"node": ">= 20.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build:all": "npm run build all && npm run build:i18n && npm run build:ts && npm run build:docs",
|
||||
"lint": "npx eslint packages/*/{src,types,package.json} --fix",
|
||||
"bootstrap": "npx lerna link",
|
||||
"postinstall": "npx lerna run prepare",
|
||||
"build:ts": "node ./scripts/build-ts.js",
|
||||
"build:docs": "node ./scripts/build-docs.js",
|
||||
"build:i18n": "node ./scripts/build-i18n.js",
|
||||
"trans:docs": "node ./scripts/trans-docs.js",
|
||||
"create:plugin": "node ./scripts/plugin/create.js",
|
||||
"lint": "npx eslint packages/*/{src,types,package.json} --fix",
|
||||
"dev": "npx cross-env NODE_ENV=development node ./scripts/dev.js",
|
||||
"build": "npx cross-env NODE_ENV=production node ./scripts/build.js",
|
||||
"postinstall": "npx lerna run prepare",
|
||||
"bootstrap": "npx lerna link"
|
||||
"build:all": "npm run build all && npm run build:i18n && npm run build:ts && npm run build:docs"
|
||||
},
|
||||
"browserslist": "last 1 Chrome version",
|
||||
"dependencies": {
|
||||
@@ -52,7 +52,6 @@
|
||||
"dotenv": "^17.2.1",
|
||||
"eslint": "^9.32.0",
|
||||
"glob": "^11.0.3",
|
||||
"globals": "^16.3.0",
|
||||
"lerna": "^8.2.3",
|
||||
"prompts": "^2.4.2",
|
||||
"servor": "^4.0.2",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import spawn from 'cross-spawn';
|
||||
import process from 'node:process'
|
||||
import spawn from 'cross-spawn'
|
||||
|
||||
const proc = spawn('npm', ['run', 'build'], {
|
||||
cwd: './packages/artplayer-vitepress/',
|
||||
});
|
||||
cwd: './packages/artplayer-vitepress/',
|
||||
})
|
||||
|
||||
proc.stdout.pipe(process.stdout);
|
||||
proc.stderr.pipe(process.stderr);
|
||||
proc.stdout.pipe(process.stdout)
|
||||
proc.stderr.pipe(process.stderr)
|
||||
+37
-36
@@ -1,45 +1,46 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { glob } from 'glob';
|
||||
import { Parcel } from '@parcel/core';
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { Parcel } from '@parcel/core'
|
||||
import { glob } from 'glob'
|
||||
|
||||
const basePath = 'packages/artplayer';
|
||||
const basePath = 'packages/artplayer'
|
||||
|
||||
const entries = glob.sync(path.join(basePath, 'src/i18n/*.js'), {
|
||||
ignore: [path.join(basePath, 'src/i18n/index.js'), path.join(basePath, 'src/i18n/zh-cn.js')],
|
||||
});
|
||||
ignore: [path.join(basePath, 'src/i18n/index.js'), path.join(basePath, 'src/i18n/zh-cn.js')],
|
||||
})
|
||||
|
||||
const packagePath = path.join(basePath, 'package.json');
|
||||
const packagePath = path.join(basePath, 'package.json')
|
||||
const backupPackagePath = path.join(basePath, 'package_backup.json');
|
||||
|
||||
(async function build() {
|
||||
fs.renameSync(packagePath, backupPackagePath);
|
||||
fs.renameSync(packagePath, backupPackagePath)
|
||||
|
||||
const bundler = new Parcel({
|
||||
entries: entries,
|
||||
defaultConfig: '@parcel/config-default',
|
||||
mode: 'production',
|
||||
defaultTargetOptions: {
|
||||
distDir: 'packages/artplayer/dist/i18n',
|
||||
outputFormat: 'global',
|
||||
sourceMaps: false,
|
||||
isLibrary: true,
|
||||
engines: {
|
||||
browsers: ['last 1 Chrome version'],
|
||||
},
|
||||
},
|
||||
env: {
|
||||
NODE_ENV: 'production',
|
||||
},
|
||||
});
|
||||
const bundler = new Parcel({
|
||||
entries,
|
||||
defaultConfig: '@parcel/config-default',
|
||||
mode: 'production',
|
||||
defaultTargetOptions: {
|
||||
distDir: 'packages/artplayer/dist/i18n',
|
||||
outputFormat: 'global',
|
||||
sourceMaps: false,
|
||||
isLibrary: true,
|
||||
engines: {
|
||||
browsers: ['last 1 Chrome version'],
|
||||
},
|
||||
},
|
||||
env: {
|
||||
NODE_ENV: 'production',
|
||||
},
|
||||
})
|
||||
|
||||
try {
|
||||
const { bundleGraph, buildTime } = await bundler.run();
|
||||
const bundles = bundleGraph.getBundles();
|
||||
console.log(`✨ Built [i18n] ${bundles.length} bundles in ${buildTime}ms`);
|
||||
fs.renameSync(backupPackagePath, packagePath);
|
||||
} catch (err) {
|
||||
console.log(err.diagnostics);
|
||||
fs.renameSync(backupPackagePath, packagePath);
|
||||
}
|
||||
})();
|
||||
try {
|
||||
const { bundleGraph, buildTime } = await bundler.run()
|
||||
const bundles = bundleGraph.getBundles()
|
||||
console.log(`✨ Built [i18n] ${bundles.length} bundles in ${buildTime}ms`)
|
||||
fs.renameSync(backupPackagePath, packagePath)
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err.diagnostics)
|
||||
fs.renameSync(backupPackagePath, packagePath)
|
||||
}
|
||||
})()
|
||||
+126
-124
@@ -1,161 +1,163 @@
|
||||
import fs from 'fs';
|
||||
import cpy from 'cpy';
|
||||
import path from 'path';
|
||||
import prompts from 'prompts';
|
||||
import { Parcel } from '@parcel/core';
|
||||
import { getProjects } from './utils.js';
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { Parcel } from '@parcel/core'
|
||||
import cpy from 'cpy'
|
||||
import prompts from 'prompts'
|
||||
import { getProjects } from './utils.js'
|
||||
|
||||
const projects = getProjects();
|
||||
const compiledPath = path.resolve('docs/compiled');
|
||||
const projects = getProjects()
|
||||
const compiledPath = path.resolve('docs/compiled')
|
||||
|
||||
function compressString(input) {
|
||||
return input
|
||||
.replace(/\s*(<[^>]+>)\s*/g, '$1')
|
||||
.replace(/(\r\n|\n|\r)/gm, ' ')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim();
|
||||
return input
|
||||
.replace(/\s*(<[^>]+>)\s*/g, '$1')
|
||||
.replace(/(\r\n|\n|\r)/g, ' ')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim()
|
||||
}
|
||||
|
||||
async function build(name, targetName) {
|
||||
const projectPackageJson = path.join(projects[name], 'package.json');
|
||||
const { version } = JSON.parse(fs.readFileSync(projectPackageJson, 'utf-8'));
|
||||
const projectPackageJson = path.join(projects[name], 'package.json')
|
||||
const { version } = JSON.parse(fs.readFileSync(projectPackageJson, 'utf-8'))
|
||||
|
||||
process.chdir(projects[name]);
|
||||
process.chdir(projects[name])
|
||||
|
||||
const targets = {
|
||||
main: {
|
||||
context: 'browser',
|
||||
distDir: path.join(projects[name], 'dist'),
|
||||
sourceMap: false,
|
||||
outputFormat: 'global',
|
||||
isLibrary: true,
|
||||
engines: {
|
||||
browsers: 'last 1 Chrome version',
|
||||
},
|
||||
},
|
||||
legacy: {
|
||||
context: 'browser',
|
||||
distDir: path.join(projects[name], 'dist'),
|
||||
sourceMap: false,
|
||||
outputFormat: 'global',
|
||||
isLibrary: true,
|
||||
engines: {
|
||||
browsers: 'IE 11',
|
||||
},
|
||||
},
|
||||
esm: {
|
||||
context: 'browser',
|
||||
distDir: path.join(projects[name], 'dist'),
|
||||
sourceMap: true,
|
||||
outputFormat: 'esmodule',
|
||||
isLibrary: true,
|
||||
engines: {
|
||||
browsers: 'last 1 Chrome version',
|
||||
},
|
||||
},
|
||||
};
|
||||
const targets = {
|
||||
main: {
|
||||
context: 'browser',
|
||||
distDir: path.join(projects[name], 'dist'),
|
||||
sourceMap: false,
|
||||
outputFormat: 'global',
|
||||
isLibrary: true,
|
||||
engines: {
|
||||
browsers: 'last 1 Chrome version',
|
||||
},
|
||||
},
|
||||
legacy: {
|
||||
context: 'browser',
|
||||
distDir: path.join(projects[name], 'dist'),
|
||||
sourceMap: false,
|
||||
outputFormat: 'global',
|
||||
isLibrary: true,
|
||||
engines: {
|
||||
browsers: 'IE 11',
|
||||
},
|
||||
},
|
||||
esm: {
|
||||
context: 'browser',
|
||||
distDir: path.join(projects[name], 'dist'),
|
||||
sourceMap: true,
|
||||
outputFormat: 'esmodule',
|
||||
isLibrary: true,
|
||||
engines: {
|
||||
browsers: 'last 1 Chrome version',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const names = {
|
||||
main: name,
|
||||
legacy: `${name}.legacy`,
|
||||
esm: `${name}.esm`,
|
||||
};
|
||||
const names = {
|
||||
main: name,
|
||||
legacy: `${name}.legacy`,
|
||||
esm: `${name}.esm`,
|
||||
}
|
||||
|
||||
const entryFile = path.join(projects[name], 'src/index.js');
|
||||
const entryFile = path.join(projects[name], 'src/index.js')
|
||||
|
||||
const bundler = new Parcel({
|
||||
entries: entryFile,
|
||||
defaultConfig: '@parcel/config-default',
|
||||
mode: 'production',
|
||||
targets: {
|
||||
[targetName]: targets[targetName],
|
||||
},
|
||||
env: {
|
||||
NODE_ENV: 'production',
|
||||
},
|
||||
});
|
||||
const bundler = new Parcel({
|
||||
entries: entryFile,
|
||||
defaultConfig: '@parcel/config-default',
|
||||
mode: 'production',
|
||||
targets: {
|
||||
[targetName]: targets[targetName],
|
||||
},
|
||||
env: {
|
||||
NODE_ENV: 'production',
|
||||
},
|
||||
})
|
||||
|
||||
const banner = `
|
||||
const banner = `
|
||||
/*!
|
||||
* ${name}.js v${version}
|
||||
* Github: https://github.com/zhw2590582/ArtPlayer
|
||||
* (c) 2017-${new Date().getFullYear()} Harvey Zack
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
`;
|
||||
`
|
||||
|
||||
const { bundleGraph, buildTime } = await bundler.run();
|
||||
const bundles = bundleGraph.getBundles();
|
||||
const { bundleGraph, buildTime } = await bundler.run()
|
||||
const bundles = bundleGraph.getBundles()
|
||||
|
||||
const filePath = path.join(projects[name], 'dist/index.js');
|
||||
const newFilePath = path.join(projects[name], `dist/${names[targetName]}.js`);
|
||||
const code = fs.readFileSync(filePath, 'utf-8');
|
||||
const filePath = path.join(projects[name], 'dist/index.js')
|
||||
const newFilePath = path.join(projects[name], `dist/${names[targetName]}.js`)
|
||||
const code = fs.readFileSync(filePath, 'utf-8')
|
||||
|
||||
fs.writeFileSync(filePath, banner + compressString(code));
|
||||
fs.renameSync(filePath, newFilePath);
|
||||
const size = fs.statSync(newFilePath).size / 1024;
|
||||
await cpy(newFilePath, compiledPath);
|
||||
fs.writeFileSync(filePath, banner + compressString(code))
|
||||
fs.renameSync(filePath, newFilePath)
|
||||
const size = fs.statSync(newFilePath).size / 1024
|
||||
await cpy(newFilePath, compiledPath)
|
||||
|
||||
if (targetName === 'esm') {
|
||||
const jsFile = path.join(projects[name], `dist/${names.esm}.js`);
|
||||
const oldMapName = 'index.js.map';
|
||||
const newMapName = `${names.esm}.js.map`;
|
||||
if (targetName === 'esm') {
|
||||
const jsFile = path.join(projects[name], `dist/${names.esm}.js`)
|
||||
const oldMapName = 'index.js.map'
|
||||
const newMapName = `${names.esm}.js.map`
|
||||
|
||||
const oldMapPath = path.join(projects[name], 'dist', oldMapName);
|
||||
const newMapPath = path.join(projects[name], 'dist', newMapName);
|
||||
if (fs.existsSync(oldMapPath)) {
|
||||
fs.renameSync(oldMapPath, newMapPath);
|
||||
}
|
||||
|
||||
let jsContent = fs.readFileSync(jsFile, 'utf8');
|
||||
jsContent = jsContent.replace(/\/\/# sourceMappingURL=.*\.js\.map/, `\n//# sourceMappingURL=${newMapName}`);
|
||||
fs.writeFileSync(jsFile, jsContent);
|
||||
await cpy(newMapPath, compiledPath);
|
||||
await cpy(newFilePath, compiledPath);
|
||||
const oldMapPath = path.join(projects[name], 'dist', oldMapName)
|
||||
const newMapPath = path.join(projects[name], 'dist', newMapName)
|
||||
if (fs.existsSync(oldMapPath)) {
|
||||
fs.renameSync(oldMapPath, newMapPath)
|
||||
}
|
||||
|
||||
console.log(
|
||||
`✨ Built@${targetName} ${name}@${version}`,
|
||||
`Bundles@${bundles.length}`,
|
||||
`Time@${buildTime}ms`,
|
||||
`Size@${size.toFixed(2)}kb`,
|
||||
);
|
||||
let jsContent = fs.readFileSync(jsFile, 'utf8')
|
||||
jsContent = jsContent.replace(/\/\/# sourceMappingURL=.*\.js\.map/, `\n//# sourceMappingURL=${newMapName}`)
|
||||
fs.writeFileSync(jsFile, jsContent)
|
||||
await cpy(newMapPath, compiledPath)
|
||||
await cpy(newFilePath, compiledPath)
|
||||
}
|
||||
|
||||
console.log(
|
||||
`✨ Built@${targetName} ${name}@${version}`,
|
||||
`Bundles@${bundles.length}`,
|
||||
`Time@${buildTime}ms`,
|
||||
`Size@${size.toFixed(2)}kb`,
|
||||
)
|
||||
}
|
||||
|
||||
async function runBuild() {
|
||||
if (process.argv.pop() === 'all') {
|
||||
const bundles = Object.keys(projects).map((name) => async () => {
|
||||
await build(name, 'main');
|
||||
await build(name, 'legacy');
|
||||
await build(name, 'esm');
|
||||
});
|
||||
if (process.argv.pop() === 'all') {
|
||||
const bundles = Object.keys(projects).map(name => async () => {
|
||||
await build(name, 'main')
|
||||
await build(name, 'legacy')
|
||||
await build(name, 'esm')
|
||||
})
|
||||
|
||||
await runPromisesInSeries(bundles);
|
||||
console.log('✅ Finished building all packages!');
|
||||
} else {
|
||||
const response = await prompts({
|
||||
type: 'select',
|
||||
name: 'value',
|
||||
message: 'Which project do you want to build?',
|
||||
choices: Object.keys(projects).map((name) => ({
|
||||
title: name,
|
||||
value: name,
|
||||
})),
|
||||
initial: 0,
|
||||
});
|
||||
await runPromisesInSeries(bundles)
|
||||
console.log('✅ Finished building all packages!')
|
||||
}
|
||||
else {
|
||||
const response = await prompts({
|
||||
type: 'select',
|
||||
name: 'value',
|
||||
message: 'Which project do you want to build?',
|
||||
choices: Object.keys(projects).map(name => ({
|
||||
title: name,
|
||||
value: name,
|
||||
})),
|
||||
initial: 0,
|
||||
})
|
||||
|
||||
if (response.value) {
|
||||
await build(response.value, 'main');
|
||||
await build(response.value, 'legacy');
|
||||
await build(response.value, 'esm');
|
||||
}
|
||||
if (response.value) {
|
||||
await build(response.value, 'main')
|
||||
await build(response.value, 'legacy')
|
||||
await build(response.value, 'esm')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runPromisesInSeries(ps) {
|
||||
return ps.reduce((p, next) => p.then(next), Promise.resolve());
|
||||
return ps.reduce((p, next) => p.then(next), Promise.resolve())
|
||||
}
|
||||
|
||||
runBuild().catch((error) => {
|
||||
console.error('❌ Build script encountered an error:', error);
|
||||
});
|
||||
console.error('❌ Build script encountered an error:', error)
|
||||
})
|
||||
+78
-76
@@ -1,92 +1,94 @@
|
||||
import path from 'path';
|
||||
import servor from 'servor';
|
||||
import prompts from 'prompts';
|
||||
import { Parcel } from '@parcel/core';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { getProjects } from './utils.js';
|
||||
import openBrowser from 'servor/utils/openBrowser.js';
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { Parcel } from '@parcel/core'
|
||||
import prompts from 'prompts'
|
||||
import servor from 'servor'
|
||||
import openBrowser from 'servor/utils/openBrowser.js'
|
||||
import { getProjects } from './utils.js'
|
||||
|
||||
const projects = getProjects();
|
||||
const projects = getProjects()
|
||||
|
||||
async function develop(name) {
|
||||
const projectPath = projects[name];
|
||||
const uncompiledPath = path.resolve(`docs/uncompiled/${name}`);
|
||||
const entryFile = path.join(projectPath, 'src/index.js');
|
||||
const projectPath = projects[name]
|
||||
const uncompiledPath = path.resolve(`docs/uncompiled/${name}`)
|
||||
const entryFile = path.join(projectPath, 'src/index.js')
|
||||
|
||||
let isOpenBrowser = false;
|
||||
let isOpenBrowser = false
|
||||
|
||||
const { url } = await servor({
|
||||
root: 'docs',
|
||||
fallback: 'index.html',
|
||||
reload: true,
|
||||
port: 8082,
|
||||
});
|
||||
const { url } = await servor({
|
||||
root: 'docs',
|
||||
fallback: 'index.html',
|
||||
reload: true,
|
||||
port: 8082,
|
||||
})
|
||||
|
||||
process.chdir(projectPath);
|
||||
process.chdir(projectPath)
|
||||
|
||||
const bundler = new Parcel({
|
||||
entries: entryFile,
|
||||
defaultConfig: '@parcel/config-default',
|
||||
mode: 'development',
|
||||
targets: {
|
||||
main: {
|
||||
distDir: uncompiledPath,
|
||||
outputFormat: 'global',
|
||||
isLibrary: true,
|
||||
engines: {
|
||||
browsers: ['last 1 Chrome version'],
|
||||
},
|
||||
},
|
||||
const bundler = new Parcel({
|
||||
entries: entryFile,
|
||||
defaultConfig: '@parcel/config-default',
|
||||
mode: 'development',
|
||||
targets: {
|
||||
main: {
|
||||
distDir: uncompiledPath,
|
||||
outputFormat: 'global',
|
||||
isLibrary: true,
|
||||
engines: {
|
||||
browsers: ['last 1 Chrome version'],
|
||||
},
|
||||
env: {
|
||||
NODE_ENV: 'development',
|
||||
},
|
||||
additionalReporters: [
|
||||
{
|
||||
packageName: '@parcel/reporter-cli',
|
||||
resolveFrom: fileURLToPath(import.meta.url),
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
},
|
||||
env: {
|
||||
NODE_ENV: 'development',
|
||||
},
|
||||
additionalReporters: [
|
||||
{
|
||||
packageName: '@parcel/reporter-cli',
|
||||
resolveFrom: fileURLToPath(import.meta.url),
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
bundler.watch((error, event) => {
|
||||
if (error) {
|
||||
console.error(`[${name}] ❌ Build error:`, error);
|
||||
return;
|
||||
}
|
||||
bundler.watch((error, event) => {
|
||||
if (error) {
|
||||
console.error(`[${name}] ❌ Build error:`, error)
|
||||
return
|
||||
}
|
||||
|
||||
if (event.type === 'buildSuccess') {
|
||||
const bundles = event.bundleGraph.getBundles();
|
||||
console.log(`[${name}] ✅ Built ${bundles.length} bundles in ${event.buildTime}ms`);
|
||||
if (!isOpenBrowser) {
|
||||
isOpenBrowser = true;
|
||||
openBrowser(url);
|
||||
}
|
||||
}
|
||||
if (event.type === 'buildSuccess') {
|
||||
const bundles = event.bundleGraph.getBundles()
|
||||
console.log(`[${name}] ✅ Built ${bundles.length} bundles in ${event.buildTime}ms`)
|
||||
if (!isOpenBrowser) {
|
||||
isOpenBrowser = true
|
||||
openBrowser(url)
|
||||
}
|
||||
}
|
||||
|
||||
if (event.type === 'buildFailure') {
|
||||
console.error(`[${name}] ❌ Build failure:`, event.diagnostics);
|
||||
}
|
||||
});
|
||||
if (event.type === 'buildFailure') {
|
||||
console.error(`[${name}] ❌ Build failure:`, event.diagnostics)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const response = await prompts({
|
||||
type: 'select',
|
||||
name: 'value',
|
||||
message: 'Which project do you want to develop?',
|
||||
choices: Object.keys(projects).map((name) => ({
|
||||
title: name,
|
||||
value: name,
|
||||
})),
|
||||
initial: 0,
|
||||
});
|
||||
try {
|
||||
const response = await prompts({
|
||||
type: 'select',
|
||||
name: 'value',
|
||||
message: 'Which project do you want to develop?',
|
||||
choices: Object.keys(projects).map(name => ({
|
||||
title: name,
|
||||
value: name,
|
||||
})),
|
||||
initial: 0,
|
||||
})
|
||||
|
||||
if (response.value) {
|
||||
await develop(response.value);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`❌ Prompt error: ${error.message}`);
|
||||
if (response.value) {
|
||||
await develop(response.value)
|
||||
}
|
||||
})();
|
||||
}
|
||||
catch (error) {
|
||||
console.error(`❌ Prompt error: ${error.message}`)
|
||||
}
|
||||
})()
|
||||
+54
-52
@@ -1,81 +1,83 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
// Get the current file path
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
const __dirname = path.dirname(__filename)
|
||||
|
||||
// Get the plugin name from command line arguments
|
||||
const args = process.argv.slice(2);
|
||||
const pluginName = args[0];
|
||||
const args = process.argv.slice(2)
|
||||
const pluginName = args[0]
|
||||
|
||||
if (!pluginName) {
|
||||
console.error('Please provide a plugin name, e.g., npm run create:plugin somePluginName');
|
||||
process.exit(1);
|
||||
console.error('Please provide a plugin name, e.g., npm run create:plugin somePluginName')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Validate plugin name
|
||||
const pluginNameRegex = /^[a-z-]+$/;
|
||||
const pluginNameRegex = /^[a-z-]+$/
|
||||
if (!pluginNameRegex.test(pluginName)) {
|
||||
console.error('Invalid plugin name. Only lowercase letters and hyphens are allowed.');
|
||||
process.exit(1);
|
||||
console.error('Invalid plugin name. Only lowercase letters and hyphens are allowed.')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Convert plugin name to export name (PascalCase)
|
||||
const exportName = pluginName
|
||||
.split('-')
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join('');
|
||||
const exportNameFull = `artplayerPlugin${exportName}`;
|
||||
.split('-')
|
||||
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join('')
|
||||
const exportNameFull = `artplayerPlugin${exportName}`
|
||||
|
||||
// Define paths
|
||||
const templateDir = path.join(__dirname, 'template');
|
||||
const destDir = path.join(__dirname, '../../packages', `artplayer-plugin-${pluginName}`);
|
||||
const exampleDir = path.join(__dirname, '../../docs/assets/example');
|
||||
const exampleFileName = `${pluginName.replace(/-/g, '.')}.js`;
|
||||
const exampleFile = path.join(exampleDir, exampleFileName);
|
||||
const templateDir = path.join(__dirname, 'template')
|
||||
const destDir = path.join(__dirname, '../../packages', `artplayer-plugin-${pluginName}`)
|
||||
const exampleDir = path.join(__dirname, '../../docs/assets/example')
|
||||
const exampleFileName = `${pluginName.replace(/-/g, '.')}.js`
|
||||
const exampleFile = path.join(exampleDir, exampleFileName)
|
||||
|
||||
// Check if a plugin with the same name already exists
|
||||
if (fs.existsSync(destDir)) {
|
||||
console.error(`Plugin ${pluginName} already exists. Please choose another name.`);
|
||||
process.exit(1);
|
||||
console.error(`Plugin ${pluginName} already exists. Please choose another name.`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Create the destination directory
|
||||
fs.mkdirSync(destDir, { recursive: true });
|
||||
fs.mkdirSync(destDir, { recursive: true })
|
||||
|
||||
// Read files from the template directory and copy them to the destination directory
|
||||
function copyTemplateFiles(templateDir, destDir) {
|
||||
const files = fs.readdirSync(templateDir);
|
||||
const files = fs.readdirSync(templateDir)
|
||||
|
||||
files.forEach((file) => {
|
||||
const templateFilePath = path.join(templateDir, file);
|
||||
let destFilePath = path.join(destDir, file);
|
||||
files.forEach((file) => {
|
||||
const templateFilePath = path.join(templateDir, file)
|
||||
let destFilePath = path.join(destDir, file)
|
||||
|
||||
const stats = fs.statSync(templateFilePath);
|
||||
const stats = fs.statSync(templateFilePath)
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
fs.mkdirSync(destFilePath, { recursive: true });
|
||||
copyTemplateFiles(templateFilePath, destFilePath);
|
||||
} else {
|
||||
// Replace placeholders in the file name
|
||||
destFilePath = destFilePath.replace(/{{name}}/g, pluginName);
|
||||
if (stats.isDirectory()) {
|
||||
fs.mkdirSync(destFilePath, { recursive: true })
|
||||
copyTemplateFiles(templateFilePath, destFilePath)
|
||||
}
|
||||
else {
|
||||
// Replace placeholders in the file name
|
||||
destFilePath = destFilePath.replace(/\{\{name\}\}/g, pluginName)
|
||||
|
||||
let content = fs.readFileSync(templateFilePath, 'utf8');
|
||||
let content = fs.readFileSync(templateFilePath, 'utf8')
|
||||
|
||||
// Replace placeholders in the file content
|
||||
content = content.replace(/{{name}}/g, pluginName);
|
||||
content = content.replace(/{{export}}/g, exportNameFull);
|
||||
// Replace placeholders in the file content
|
||||
content = content.replace(/\{\{name\}\}/g, pluginName)
|
||||
content = content.replace(/\{\{export\}\}/g, exportNameFull)
|
||||
|
||||
fs.writeFileSync(destFilePath, content);
|
||||
}
|
||||
});
|
||||
fs.writeFileSync(destFilePath, content)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Create the example file
|
||||
function createExampleFile() {
|
||||
const exampleContent = `
|
||||
const exampleContent = `
|
||||
// npm i artplayer-plugin-${pluginName}
|
||||
// import ${exportNameFull} from 'artplayer-plugin-${pluginName}';
|
||||
|
||||
@@ -88,18 +90,18 @@ var art = new Artplayer({
|
||||
}),
|
||||
],
|
||||
});
|
||||
`.trim();
|
||||
`.trim()
|
||||
|
||||
if (!fs.existsSync(exampleDir)) {
|
||||
fs.mkdirSync(exampleDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(exampleDir)) {
|
||||
fs.mkdirSync(exampleDir, { recursive: true })
|
||||
}
|
||||
|
||||
fs.writeFileSync(exampleFile, exampleContent);
|
||||
console.log(`Example file created at ${exampleFile}`);
|
||||
fs.writeFileSync(exampleFile, exampleContent)
|
||||
console.log(`Example file created at ${exampleFile}`)
|
||||
}
|
||||
|
||||
// Start copying template files and creating example file
|
||||
copyTemplateFiles(templateDir, destDir);
|
||||
createExampleFile();
|
||||
copyTemplateFiles(templateDir, destDir)
|
||||
createExampleFile()
|
||||
|
||||
console.log(`Plugin ${pluginName} has been successfully created at ${destDir}`);
|
||||
console.log(`Plugin ${pluginName} has been successfully created at ${destDir}`)
|
||||
@@ -1,24 +1,24 @@
|
||||
{
|
||||
"license": "MIT",
|
||||
"version": "1.0.0",
|
||||
"name": "artplayer-plugin-{{name}}",
|
||||
"types": "types/artplayer-plugin-{{name}}.d.ts",
|
||||
"description": "{{name}} plugin for ArtPlayer",
|
||||
"main": "dist/artplayer-plugin-{{name}}.js",
|
||||
"legacy": "dist/artplayer-plugin-{{name}}.legacy.js",
|
||||
"author": "Harvey Zack <laozhaochaguan@gmail.com>",
|
||||
"browserslist": "last 1 Chrome version",
|
||||
"homepage": "https://artplayer.org",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/zhw2590582/ArtPlayer.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/zhw2590582/ArtPlayer/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"html5",
|
||||
"video",
|
||||
"player"
|
||||
]
|
||||
"name": "artplayer-plugin-{{name}}",
|
||||
"version": "1.0.0",
|
||||
"description": "{{name}} plugin for ArtPlayer",
|
||||
"author": "Harvey Zack <laozhaochaguan@gmail.com>",
|
||||
"license": "MIT",
|
||||
"homepage": "https://artplayer.org",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/zhw2590582/ArtPlayer.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/zhw2590582/ArtPlayer/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"html5",
|
||||
"video",
|
||||
"player"
|
||||
],
|
||||
"main": "dist/artplayer-plugin-{{name}}.js",
|
||||
"types": "types/artplayer-plugin-{{name}}.d.ts",
|
||||
"legacy": "dist/artplayer-plugin-{{name}}.legacy.js",
|
||||
"browserslist": "last 1 Chrome version"
|
||||
}
|
||||
+143
-139
@@ -1,171 +1,175 @@
|
||||
import fs from 'fs';
|
||||
import cpy from 'cpy';
|
||||
import path from 'path';
|
||||
import { glob } from 'glob';
|
||||
import { removeDir } from './utils.js';
|
||||
import dotenv from 'dotenv';
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import cpy from 'cpy'
|
||||
import dotenv from 'dotenv'
|
||||
import { glob } from 'glob'
|
||||
import { removeDir } from './utils.js'
|
||||
|
||||
dotenv.config();
|
||||
dotenv.config()
|
||||
|
||||
// 配置常量
|
||||
const MAX_RETRIES = 3;
|
||||
const RETRY_DELAY = 1000; // 1秒
|
||||
const MAX_CHARS_PER_REQUEST = 128000;
|
||||
const BASE_PATH = 'packages/artplayer-vitepress/docs';
|
||||
const EN_PATH = 'packages/artplayer-vitepress/docs/en';
|
||||
const COPY_DIRS = ['advanced', 'component', 'plugin', 'start'];
|
||||
const MAX_RETRIES = 3
|
||||
const RETRY_DELAY = 1000 // 1秒
|
||||
const MAX_CHARS_PER_REQUEST = 128000
|
||||
const BASE_PATH = 'packages/artplayer-vitepress/docs'
|
||||
const EN_PATH = 'packages/artplayer-vitepress/docs/en'
|
||||
const COPY_DIRS = ['advanced', 'component', 'plugin', 'start']
|
||||
|
||||
function splitMarkdown(text, maxChars) {
|
||||
const parts = [];
|
||||
let currentPart = '';
|
||||
let inCodeBlock = false;
|
||||
let inSpecialBlock = false;
|
||||
const parts = []
|
||||
let currentPart = ''
|
||||
let inCodeBlock = false
|
||||
let inSpecialBlock = false
|
||||
|
||||
const lines = text.split('\n');
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
const lines = text.split('\n')
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i]
|
||||
|
||||
// 检测代码块
|
||||
if (line.trim().startsWith('```')) {
|
||||
inCodeBlock = !inCodeBlock;
|
||||
}
|
||||
|
||||
// 检测特殊块
|
||||
if (line.trim().startsWith(':::')) {
|
||||
inSpecialBlock = !inSpecialBlock;
|
||||
}
|
||||
|
||||
// 添加当前行到当前部分
|
||||
currentPart += line + '\n';
|
||||
|
||||
// 检测是否达到字符限制
|
||||
if (!inCodeBlock && !inSpecialBlock && currentPart.length > maxChars && i < lines.length - 1) {
|
||||
parts.push(currentPart);
|
||||
currentPart = '';
|
||||
}
|
||||
// 检测代码块
|
||||
if (line.trim().startsWith('```')) {
|
||||
inCodeBlock = !inCodeBlock
|
||||
}
|
||||
|
||||
// 添加最后一部分
|
||||
if (currentPart !== '') {
|
||||
parts.push(currentPart);
|
||||
// 检测特殊块
|
||||
if (line.trim().startsWith(':::')) {
|
||||
inSpecialBlock = !inSpecialBlock
|
||||
}
|
||||
|
||||
return parts;
|
||||
// 添加当前行到当前部分
|
||||
currentPart += `${line}\n`
|
||||
|
||||
// 检测是否达到字符限制
|
||||
if (!inCodeBlock && !inSpecialBlock && currentPart.length > maxChars && i < lines.length - 1) {
|
||||
parts.push(currentPart)
|
||||
currentPart = ''
|
||||
}
|
||||
}
|
||||
|
||||
// 添加最后一部分
|
||||
if (currentPart !== '') {
|
||||
parts.push(currentPart)
|
||||
}
|
||||
|
||||
return parts
|
||||
}
|
||||
|
||||
async function fetchWithRetry(url, options, retries = MAX_RETRIES) {
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
...options,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...options.headers,
|
||||
},
|
||||
});
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
...options,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...options.headers,
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
if (retries > 0) {
|
||||
console.log(`Retrying... (${MAX_RETRIES - retries + 1}/${MAX_RETRIES})`);
|
||||
await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY));
|
||||
return fetchWithRetry(url, options, retries - 1);
|
||||
}
|
||||
throw error;
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
return await response.json()
|
||||
}
|
||||
catch (error) {
|
||||
if (retries > 0) {
|
||||
console.log(`Retrying... (${MAX_RETRIES - retries + 1}/${MAX_RETRIES})`)
|
||||
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY))
|
||||
return fetchWithRetry(url, options, retries - 1)
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
const translateContent = async (content, targetLanguage) => {
|
||||
try {
|
||||
const TRANSLATE_URL = 'https://api.deepseek.com/chat/completions';
|
||||
const response = await fetchWithRetry(TRANSLATE_URL, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.DEEPL_API_KEY}`,
|
||||
},
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
stream: false,
|
||||
model: 'deepseek-chat',
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: `The following text is written in VitePress's extended Markdown syntax, Please translate it into ${targetLanguage}, and keep the Markdown format and don't add your explanation:\n\n${content}`,
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
async function translateContent(content, targetLanguage) {
|
||||
try {
|
||||
const TRANSLATE_URL = 'https://api.deepseek.com/chat/completions'
|
||||
const response = await fetchWithRetry(TRANSLATE_URL, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.DEEPL_API_KEY}`,
|
||||
},
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
stream: false,
|
||||
model: 'deepseek-chat',
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: `The following text is written in VitePress's extended Markdown syntax, Please translate it into ${targetLanguage}, and keep the Markdown format and don't add your explanation:\n\n${content}`,
|
||||
},
|
||||
],
|
||||
}),
|
||||
})
|
||||
|
||||
return response.choices[0].message.content;
|
||||
} catch (error) {
|
||||
console.error(`Translation failed: ${error.message}`);
|
||||
return content; // 返回原文作为回退
|
||||
}
|
||||
};
|
||||
return response.choices[0].message.content
|
||||
}
|
||||
catch (error) {
|
||||
console.error(`Translation failed: ${error.message}`)
|
||||
return content // 返回原文作为回退
|
||||
}
|
||||
}
|
||||
|
||||
class ProgressTracker {
|
||||
constructor(totalParts) {
|
||||
this.totalParts = totalParts;
|
||||
this.translatedPartsCount = 0;
|
||||
}
|
||||
constructor(totalParts) {
|
||||
this.totalParts = totalParts
|
||||
this.translatedPartsCount = 0
|
||||
}
|
||||
|
||||
update() {
|
||||
this.translatedPartsCount++;
|
||||
const progressPercentage = ((this.translatedPartsCount / this.totalParts) * 100).toFixed(2);
|
||||
console.log(`Overall progress: ${progressPercentage}% (${this.translatedPartsCount}/${this.totalParts})`);
|
||||
}
|
||||
update() {
|
||||
this.translatedPartsCount++
|
||||
const progressPercentage = ((this.translatedPartsCount / this.totalParts) * 100).toFixed(2)
|
||||
console.log(`Overall progress: ${progressPercentage}% (${this.translatedPartsCount}/${this.totalParts})`)
|
||||
}
|
||||
}
|
||||
|
||||
const translateMarkdownFiles = async (filePaths, targetLanguage, maxCharsPerRequest) => {
|
||||
// 先计算总共有多少部分需要翻译
|
||||
let totalParts = 0;
|
||||
for (const filePath of filePaths) {
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
totalParts += splitMarkdown(content, maxCharsPerRequest).length;
|
||||
async function translateMarkdownFiles(filePaths, targetLanguage, maxCharsPerRequest) {
|
||||
// 先计算总共有多少部分需要翻译
|
||||
let totalParts = 0
|
||||
for (const filePath of filePaths) {
|
||||
const content = fs.readFileSync(filePath, 'utf-8')
|
||||
totalParts += splitMarkdown(content, maxCharsPerRequest).length
|
||||
}
|
||||
|
||||
console.log(`Starting translation of ${filePaths.length} files, total ${totalParts} parts.`)
|
||||
const progressTracker = new ProgressTracker(totalParts)
|
||||
|
||||
for (const filePath of filePaths) {
|
||||
console.log(`Translating: ${path.relative(EN_PATH, filePath)}`)
|
||||
|
||||
const content = fs.readFileSync(filePath, 'utf-8')
|
||||
const parts = splitMarkdown(content, maxCharsPerRequest)
|
||||
const translatedParts = []
|
||||
|
||||
for (const part of parts) {
|
||||
const translatedPart = await translateContent(part, targetLanguage)
|
||||
translatedParts.push(translatedPart)
|
||||
progressTracker.update()
|
||||
}
|
||||
|
||||
console.log(`Starting translation of ${filePaths.length} files, total ${totalParts} parts.`);
|
||||
const progressTracker = new ProgressTracker(totalParts);
|
||||
|
||||
for (const filePath of filePaths) {
|
||||
console.log(`Translating: ${path.relative(EN_PATH, filePath)}`);
|
||||
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
const parts = splitMarkdown(content, maxCharsPerRequest);
|
||||
const translatedParts = [];
|
||||
|
||||
for (const part of parts) {
|
||||
const translatedPart = await translateContent(part, targetLanguage);
|
||||
translatedParts.push(translatedPart);
|
||||
progressTracker.update();
|
||||
}
|
||||
|
||||
const translatedContent = translatedParts.join('\n');
|
||||
fs.writeFileSync(filePath, translatedContent);
|
||||
}
|
||||
};
|
||||
const translatedContent = translatedParts.join('\n')
|
||||
fs.writeFileSync(filePath, translatedContent)
|
||||
}
|
||||
}
|
||||
|
||||
async function setupDirectoryStructure() {
|
||||
// 清理并创建目录结构
|
||||
removeDir(EN_PATH);
|
||||
await cpy(path.resolve(BASE_PATH, 'index.md'), path.resolve(EN_PATH));
|
||||
// 清理并创建目录结构
|
||||
removeDir(EN_PATH)
|
||||
await cpy(path.resolve(BASE_PATH, 'index.md'), path.resolve(EN_PATH))
|
||||
|
||||
// 并行复制所有目录
|
||||
await Promise.all(
|
||||
COPY_DIRS.map((dir) => cpy(path.resolve(BASE_PATH, dir), path.resolve(EN_PATH, dir), { flat: true })),
|
||||
);
|
||||
// 并行复制所有目录
|
||||
await Promise.all(
|
||||
COPY_DIRS.map(dir => cpy(path.resolve(BASE_PATH, dir), path.resolve(EN_PATH, dir), { flat: true })),
|
||||
)
|
||||
}
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
await setupDirectoryStructure();
|
||||
const mdsPaths = glob.sync(path.resolve(EN_PATH, '**/*.md'));
|
||||
await translateMarkdownFiles(mdsPaths, 'English', MAX_CHARS_PER_REQUEST);
|
||||
console.log('Translation completed successfully!');
|
||||
} catch (error) {
|
||||
console.error('Translation failed:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
try {
|
||||
await setupDirectoryStructure()
|
||||
const mdsPaths = glob.sync(path.resolve(EN_PATH, '**/*.md'))
|
||||
await translateMarkdownFiles(mdsPaths, 'English', MAX_CHARS_PER_REQUEST)
|
||||
console.log('Translation completed successfully!')
|
||||
}
|
||||
catch (error) {
|
||||
console.error('Translation failed:', error)
|
||||
process.exit(1)
|
||||
}
|
||||
})()
|
||||
+26
-24
@@ -1,30 +1,32 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { glob } from 'glob';
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { glob } from 'glob'
|
||||
|
||||
export function getProjects() {
|
||||
return glob
|
||||
.sync('packages/*')
|
||||
.sort()
|
||||
.filter((item) => !item.endsWith('artplayer-template') && !item.endsWith('artplayer-vitepress'))
|
||||
.reduce((result, item) => {
|
||||
const name = item.split(/\/|\\/g).pop();
|
||||
result[name] = path.resolve(process.cwd(), item);
|
||||
return result;
|
||||
}, {});
|
||||
return glob
|
||||
.sync('packages/*')
|
||||
.sort()
|
||||
.filter(item => !item.endsWith('artplayer-template') && !item.endsWith('artplayer-vitepress'))
|
||||
.reduce((result, item) => {
|
||||
const name = item.split(/\/|\\/g).pop()
|
||||
result[name] = path.resolve(process.cwd(), item)
|
||||
return result
|
||||
}, {})
|
||||
}
|
||||
|
||||
export function removeDir(dir) {
|
||||
if (fs.existsSync(dir)) {
|
||||
const files = fs.readdirSync(dir);
|
||||
files.forEach((file) => {
|
||||
const curPath = path.join(dir, file);
|
||||
if (fs.statSync(curPath).isDirectory()) {
|
||||
removeDir(curPath);
|
||||
} else {
|
||||
fs.unlinkSync(curPath);
|
||||
}
|
||||
});
|
||||
fs.rmdirSync(dir);
|
||||
}
|
||||
if (fs.existsSync(dir)) {
|
||||
const files = fs.readdirSync(dir)
|
||||
files.forEach((file) => {
|
||||
const curPath = path.join(dir, file)
|
||||
if (fs.statSync(curPath).isDirectory()) {
|
||||
removeDir(curPath)
|
||||
}
|
||||
else {
|
||||
fs.unlinkSync(curPath)
|
||||
}
|
||||
})
|
||||
fs.rmdirSync(dir)
|
||||
}
|
||||
}
|
||||
+9
-9
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"plugins": [
|
||||
{
|
||||
"name": "preset-default",
|
||||
"params": {
|
||||
"overrides": {
|
||||
"removeViewBox": false
|
||||
}
|
||||
}
|
||||
"plugins": [
|
||||
{
|
||||
"name": "preset-default",
|
||||
"params": {
|
||||
"overrides": {
|
||||
"removeViewBox": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user