Skip to content

Commit

Permalink
feat(utils): 新增utils包,其内置各种实用工具。其中新增脚本打包器,可对打包流程进行优化。
Browse files Browse the repository at this point in the history
  • Loading branch information
enncy committed Aug 26, 2022
1 parent 389de41 commit 01879dd
Show file tree
Hide file tree
Showing 12 changed files with 412 additions and 61 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ package-lock.json
pnpm-lock.yaml
public
stats.html
tests/*
.md
15 changes: 15 additions & 0 deletions packages/core/entry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* eslint-disable no-undef */

(function () {
'use strict';

// 运行脚本
OCS.start({
// 加载样式
style: OCS_STYLE,
// 支持拖动
draggable: true,
// 加载默认脚本列表,默认 OCS.definedScripts
scripts: OCS.definedScripts
});
})();
2 changes: 2 additions & 0 deletions packages/core/src/env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ declare module '*.vue' {
const component: DefineComponent<{}, {}, any>;
export default component;
}

declare module 'typr.js';
145 changes: 145 additions & 0 deletions packages/utils/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# customize

tests/

pnpm-lock.yaml
package-lock.json

# vue build

public

# electron build

dist

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
28 changes: 28 additions & 0 deletions packages/utils/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "@ocsjs/utils",
"version": "1.0.0",
"description": "utils package of ocs",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"scripts": {},
"repository": {
"type": "git",
"url": "git+https://github.com/ocsjs/ocsjs.git"
},
"keywords": [
"ocs",
"script",
"playwright",
"puppeteer",
"electron",
"vue",
"ant-design-vue",
"typescript"
],
"author": "enncy",
"license": "MIT",
"bugs": {
"url": "https://github.com/ocsjs/ocsjs/issues"
},
"homepage": "https://github.com/ocsjs/ocsjs#readme"
}
1 change: 1 addition & 0 deletions packages/utils/src/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './script.builder';
153 changes: 153 additions & 0 deletions packages/utils/src/common/script.builder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { readFileSync, writeFileSync } from 'fs';
import fetch from 'node-fetch';

export type MetaDataType = string | string[];

/**
* 脚本头部信息格式
*/
export interface MetaDataFormatter {
header: string;
footer: string;
prefix: string;
symbol: string;
gap: string;
}

/**
* 脚本头部信息
*/
export interface Metadata {
[x: string]: any;
name: string;
version: string;
description: string;
author: MetaDataType;
license: string;
namespace: string;
homepage: string;
source: string;
icon: string;
connect: MetaDataType;
match: MetaDataType;
grant: MetaDataType;
require: MetaDataType;
resource: MetaDataType;
'run-at': 'document-start' | 'document-end' | 'document-idle' | 'document-body' | 'document-body';
}

/**
* 创建脚本参数
*/
export interface CreateOptions {
parseRequire: boolean;
parseResource: boolean;
resourceBuilder: (key: string, value: string) => string;
metaDataFormatter: MetaDataFormatter;
entry: string;
dist: string;
metadata: Metadata;
}

export const DEFAULT_METADATA: Partial<Metadata> = {
name: 'New Userscript',
version: '0.1',
description: 'try to take over the world!',
author: ['You'],
license: 'MIT',
match: ['http://*/*'],
grant: 'none',
'run-at': 'document-idle'
};

/**
* 创建脚本头部信息
* @param metadata
* @returns
*/
export function createUserScriptMetadata(formatter: MetaDataFormatter, metadata: Metadata) {
const contents = [];
// 最长字段
const maxLength = Object.keys(metadata).reduce<number>((pre, cur) => Math.max(cur.length, pre), 0);

const lineBuilder = (key: string, value: string) =>
[formatter.symbol, key.padEnd(maxLength, ' '), formatter.gap, value || ''].join('');

for (const key in metadata) {
if (Object.prototype.hasOwnProperty.call(metadata, key)) {
const element = metadata[key];
if (Array.isArray(element)) {
contents.push(...element.map((el) => lineBuilder(key, el)));
} else {
contents.push(lineBuilder(key, element));
}
}
}
return [formatter.header, ...contents, formatter.footer].map((line) => formatter.prefix + line).join('\n');
}

/**
* 解析脚本头部信息
* @param require 外部依赖
*/
export async function parseMetaDataRequires(require: Metadata['require']) {
const requires: string[] = [];
for (const value of Array.isArray(require) ? require : [require]) {
if (value) {
const text = value.startsWith('http')
? await fetch(value).then((res) => res.text())
: readFileSync(value).toString();
requires.push(text);
}
}
return requires.join('\n');
}

/**
* 解析脚本头部信息
* @param resource 资源信息
* @param resourceBuilder 变量声明器
*/
export async function parseMetaDataResources(
resource: Metadata['resource'],
resourceBuilder: (key: string, value: string) => string
) {
const resources: string[] = [];
for (const line of Array.isArray(resource) ? resource : [resource]) {
const values = line.replace(/ /g, ' ').split(' ');

const text = values[1].startsWith('http')
? await fetch(values[1]).then((res) => res.text())
: readFileSync(values[1]).toString();
resources.push(resourceBuilder(values[0], text));
}
return resources.join('\n');
}

/**
* 创建用户脚本
*/
export async function createUserScript(opts: CreateOptions) {
let requires = '';
let resources = '';
if (opts.parseRequire) {
// 解析外部依赖
requires = await parseMetaDataRequires(opts.metadata.require);
opts.metadata.require = [];
}
if (opts.parseResource) {
// 解析资源文件
resources = await parseMetaDataResources(opts.metadata.resource, opts.resourceBuilder);
opts.metadata.resource = [];
}
const content = [
// 创建脚本头部信息
createUserScriptMetadata(opts.metaDataFormatter, Object.assign(DEFAULT_METADATA, opts.metadata)),
requires,
resources,
// 合并入口文件
readFileSync(opts.entry).toString()
].join('\n'.repeat(2));

return writeFileSync(opts.dist, content);
}
1 change: 1 addition & 0 deletions packages/utils/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './common';
12 changes: 12 additions & 0 deletions packages/utils/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"outDir": "./lib",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true
}
}
Loading

0 comments on commit 01879dd

Please sign in to comment.