init framework

This commit is contained in:
yhh
2020-06-08 11:49:45 +08:00
parent a2fd5153ad
commit db077d187c
125 changed files with 140474 additions and 0 deletions

452
demo/scripts/api.d.ts vendored Normal file
View File

@@ -0,0 +1,452 @@
/**
* ResourceManager 配置文件
*/
type ResourceManagerConfig = {
/**
* 构建与发布配置
*/
buildConfig: (param: BuildConfigParam) => UserConfig,
/**
* 设置资源类型
*/
typeSelector: (path: string) => (string | null | undefined)
/**
* 设置资源的合并策略
*/
mergeSelector?: (path: string) => (string | null | undefined),
/**
* 设置资源的命名策略
* beta 功能,请勿随意使用
*/
nameSelector?: (path: string) => (string | null | undefined)
}
/**
* 构建配置
*/
type UserConfig = {
/**
* 输出路径
*/
outputDir: string,
/**
* 插件
*/
commands: (string | plugins.Command)[]
}
type BuildConfigParam = {
/**
* 当前命令build 或者 command
*/
readonly command: string;
/**
* 发布平台
*/
readonly target: string;
/**
* 开发者指定的版本号
*/
readonly version: string;
/**
* 项目名称
*/
readonly projectName: string;
/**
* 项目路径
*/
readonly projectRoot: string;
/**
* 项目配置
*/
readonly projectConfig: ProjectConfig;
}
type ProjectConfig = {
entryClassName: string;
orientation: string;
frameRate: number;
scaleMode: string;
contentWidth: number;
contentHeight: number;
showFPS: boolean;
fpsStyles: string;
showLog: boolean;
maxTouches: number;
}
/**
* 匹配机制,将满足 from 的文件输出为 to 格式的文件
* from 采用 glob 表达式 , to 包含 [path][name][hash][ext]四个变量
* 示例:{ from:"resource/**.*" , to:"[path][name]_[hash].[ext]" }
*/
type Matcher = {
from: string,
to: string
}
declare namespace plugins {
interface CommandContext {
/**
* 可以用此接口进行文件创建
*/
createFile(relativeFilePath: string, contents: Buffer);
/**
* 构建配置
*/
buildConfig: BuildConfigParam;
/**
* 项目绝对路径
*/
projectRoot: string;
/**
* 项目输出绝对路径
*/
outputDir: string;
}
/**
* 构建管线命令
*/
interface Command {
/**
* 项目中的每个文件都会执行此函数,返回 file 表示保留此文件,返回 null 表示将此文件从构建管线中删除,即不会发布
*/
onFile?(file: File): Promise<File | null>
/**
* 项目中所有文件均执行完后,最终会执行此函数。
* 这个函数主要被用于创建新文件
*/
onFinish?(pluginContext?: CommandContext): Promise<void>
[options: string]: any;
}
interface File {
/**
* 文件内容的二进制流,如果开发者需要修改文件内容,请修改此属性
*/
contents: Buffer;
/**
* 文件绝对路径,如果开发者需要对文件进行重命名,请修改此属性
*/
path: string;
/**
* 文件所在的项目的项目路径
*/
readonly base: string;
/**
* 文件的相对于 base 属性的相对路径
*/
readonly relative: string;
/**
* 文件变更历史history[0] 即 origin 属性
*/
readonly history: ReadonlyArray<string>;
/**
* 文件所在的文件夹的绝对路径
*/
readonly dirname: string;
/**
* 文件的文件名
*/
readonly basename: string;
/**
* 文件的扩展名
*/
readonly extname: string;
/**
* 文件的初始文件名
*/
readonly origin: string;
/**
* 其他自定义属性
*/
[customProperty: string]: any;
}
}
declare module 'built-in' {
/**
* 混淆插件参数,设置源代码和目标代码
*/
type UglifyPluginOption = { sources: string[], target: string };
type UglifyPluginOptions = UglifyPluginOption[];
/**
* 混淆插件
*/
export class UglifyPlugin implements plugins.Command {
constructor(mergeSelector: UglifyPluginOptions);
}
type LibraryType = "debug" | "release";
type CompilePluginOptions = { libraryType: LibraryType, defines?: any };
/**
* 编译命令
*/
export class CompilePlugin implements plugins.Command {
constructor(options: CompilePluginOptions);
}
/**
* EXML 插件,用于发布 EXML 文件
*/
export class ExmlPlugin implements plugins.Command {
constructor(publishPolicy: EXML_Publish_Policy);
}
/**
* 发布策略
* * debug : 默认策略,用于开发环境
* * contents : 将 EXML 的内容写入到主题文件中
* * gjs : 将生成的JS文件写入到主题文件中
* * commonjs : 将EXML合并为一个 CommonJS 风格的文件
* * commonjs2 : 将EXML合并为一个含有解析方法和皮肤定义的文件且皮肤抽离为一份配置
* * json : 将每个EXML文件生成一份配置
*/
type EXML_Publish_Policy = "debug" | "contents" | "gjs" | "commonjs" | "commonjs2" | "json"
/**
* 生成 manifest 文件,这个文件会被用于记录 JavaScript 文件的版本号
*/
export class ManifestPlugin implements plugins.Command {
constructor(options?: ManifestPluginOptions)
}
/**
* 生成文件的文件名
* 支持 json 与 js 两种格式
*/
type ManifestPluginOptions = {
output: string,
hash?: "crc32",
/**
* 是否输出转换过程
*/
verbose?: boolean,
/**
* 其他传递的消息参数
*/
info?:any
/**
* use wechat engine plugin
*/
useWxPlugin?: boolean
/**
* use QQgame engine plugin
*/
qqPlugin?: { use: boolean, pluginList: string[] }
}
/**
* EmitResConfigFilePlugin 的参数
* * output: 生成路径,可以指定生成为 *.res.js 文件或者 *.res.json 文件
* * typeSelector: 根据文件路径决定文件类型
* * nameSelector: 根据文件路径决定文件的资源名
* * groupSelector: 根据文件路径决定资源所述的资源组
*/
type EmitResConfigFilePluginOptions = {
output: string,
typeSelector: (path: string) => string | null | undefined,
nameSelector: (path: string) => string | null | undefined,
groupSelector: (path: string) => string | null | undefined,
}
/**
* 生成 res.json 文件或者 res.js 文件
*/
export class EmitResConfigFilePlugin implements plugins.Command {
constructor(options: EmitResConfigFilePluginOptions)
}
export type ConvertResourceConfigPluginOption = {
resourceConfigFiles: { filename: string, root: string }[];
nameSelector: (url: string) => string;
TM_Verbose: boolean;
}
export class ConvertResConfigFilePlugin implements plugins.Command {
constructor(options: ConvertResourceConfigPluginOption);
}
/**
* 增量编译
* 这个插件生成的 JavaScript 代码不会被添加到构建管线中,后续其他插件无法获取生成的 js 文件
* 这个功能将会在未来被 watch 模式代替掉
*/
export class IncrementCompilePlugin implements plugins.Command {
}
type TextureMergerOptions = {
textureMergerRoot: string[];
}
/**
* 使用 TextureMerger 实现纹理自动合并,依赖 TextureMerger 1.7 以上的版本
*/
export class TextureMergerPlugin implements plugins.Command {
constructor(options: TextureMergerOptions);
}
type CleanPluginOptions = {
matchers: string[]
}
export class CleanPlugin implements plugins.Command {
constructor(options: CleanPluginOptions);
}
type RenamePluginOptions = {
/**
* 是否输出日志
* Whether to output the log
*/
verbose?: boolean
/**
* 采用何种 hash 算法,目前暂时只支持 crc32
* What hash algorithm is used, currently only crc32 is supported
*/
hash?: "crc32"
/**
* 设置匹配规则,将指定文件进行改名
* 该参数是个数组,允许设置多个匹配规则
* Set up matching rules to copy specified files to other folders
* This parameter is an array that allows multiple matching rules to be set
*/
matchers: Matcher[]
/**
* 回调函数,返回值里包括文件的一些信息
* The callback function, return value includes some information about the file
*/
callback?: Function
}
/**
* 修改文件名插件
*/
export class RenamePlugin implements plugins.Command {
constructor(options: RenamePluginOptions);
}
type ResSplitPluginOptions = {
/**
* 是否输出日志
* Whether to output the log
*/
verbose?: boolean
/**
* 设置匹配规则,将指定文件拷贝至其他文件夹
* 该参数是个数组,允许设置多个匹配规则
* Set up matching rules to copy specified files to other folders
* This parameter is an array that allows multiple matching rules to be set
*/
matchers: Matcher[]
}
export class ResSplitPlugin implements plugins.Command {
constructor(options: ResSplitPluginOptions);
}
type ZipPluginOptions = {
mergeSelector: (p: string) => string
}
export class ZipPlugin implements plugins.Command {
constructor(option: ZipPluginOptions);
}
type MergeEuiJsonPluginOptions = {
mergeSelector?: (p: string) => string | null,
createConfig?: boolean
}
export class MergeEuiJsonPlugin implements plugins.Command {
constructor(option?: MergeEuiJsonPluginOptions);
}
}

View File

@@ -0,0 +1,82 @@
import * as fs from 'fs';
import * as path from 'path';
export class BaidugamePlugin implements plugins.Command {
constructor() {
}
async onFile(file: plugins.File) {
if (file.extname == '.js') {
const filename = file.origin;
if (filename == "libs/modules/promise/promise.js" || filename == 'libs/modules/promise/promise.min.js') {
return null;
}
if (filename == 'libs/modules/egret/egret.js' || filename == 'libs/modules/egret/egret.min.js') {
let content = file.contents.toString();
content += `;window.egret = egret;`;
content = content.replace(/definition = __global/, "definition = window");
file.contents = new Buffer(content);
}
else {
let content = file.contents.toString();
if (
filename == "libs/modules/res/res.js" ||
filename == 'libs/modules/res/res.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.js'
) {
content += ";window.RES = RES;"
}
if (filename == "libs/modules/eui/eui.js" || filename == 'libs/modules/eui/eui.min.js') {
content += ";window.eui = eui;"
}
if (filename == 'libs/modules/dragonBones/dragonBones.js' || filename == 'libs/modules/dragonBones/dragonBones.min.js') {
content += ';window.dragonBones = dragonBones';
}
content = "var egret = window.egret;" + content;
if (filename == 'main.js') {
content += "\n;window.Main = Main;"
}
file.contents = new Buffer(content);
}
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
//同步 index.html 配置到 game.js
const gameJSPath = path.join(pluginContext.outputDir, "game.js");
if(!fs.existsSync(gameJSPath)) {
console.log(`${gameJSPath}不存在,请先使用 Launcher 发布百度小游戏`);
return;
}
let gameJSContent = fs.readFileSync(gameJSPath, { encoding: "utf8" });
const projectConfig = pluginContext.buildConfig.projectConfig;
const optionStr =
`entryClassName: ${projectConfig.entryClassName},\n\t\t` +
`orientation: ${projectConfig.orientation},\n\t\t` +
`frameRate: ${projectConfig.frameRate},\n\t\t` +
`scaleMode: ${projectConfig.scaleMode},\n\t\t` +
`contentWidth: ${projectConfig.contentWidth},\n\t\t` +
`contentHeight: ${projectConfig.contentHeight},\n\t\t` +
`showFPS: ${projectConfig.showFPS},\n\t\t` +
`fpsStyles: ${projectConfig.fpsStyles},\n\t\t` +
`showLog: ${projectConfig.showLog},\n\t\t` +
`maxTouches: ${projectConfig.maxTouches},`;
const reg = /\/\/----auto option start----[\s\S]*\/\/----auto option end----/;
const replaceStr = '\/\/----auto option start----\n\t\t' + optionStr + '\n\t\t\/\/----auto option end----';
gameJSContent = gameJSContent.replace(reg, replaceStr);
fs.writeFileSync(gameJSPath, gameJSContent);
//修改横竖屏
let orientation;
if (projectConfig.orientation == '"landscape"') {
orientation = "landscape";
}
else {
orientation = "portrait";
}
const gameJSONPath = path.join(pluginContext.outputDir, "game.json");
let gameJSONContent = JSON.parse(fs.readFileSync(gameJSONPath, { encoding: "utf8" }));
gameJSONContent.deviceOrientation = orientation;
fs.writeFileSync(gameJSONPath, JSON.stringify(gameJSONContent, null, "\t"));
}
}

View File

@@ -0,0 +1,64 @@
import * as fs from 'fs';
import * as path from 'path';
type ManifestConfig = {
initial: string[],
game: string[]
}
export class BricksPlugin implements plugins.Command {
constructor() {
}
async onFile(file: plugins.File) {
const filename = file.basename;
if (filename == 'manifest.json') {
const contents = file.contents.toString();
const jsonData: ManifestConfig = JSON.parse(contents);
let content = '';
content += `BK.Script.loadlib("GameRes://js/promise.js");\n`;
for (let item of jsonData.initial) {
if (item != 'js/promise.js' && item != 'js/promise.min.js') {
content += `BK.Script.loadlib("GameRes://${item}");\n`
}
}
for (let item of jsonData.game) {
content += `BK.Script.loadlib("GameRes://${item}");\n`
}
content += `BK.Script.loadlib("GameRes://egret.bricks.js");\n`
file.path = file.dirname + '/manifest.js'
file.contents = new Buffer(content);
} else if (filename == 'main.js') {
const content = file.contents.toString();
let result = content.replace(/RES\.loadConfig\("resource\/default\.res\.json", "resource\/"\)/gm, 'RES.loadConfig("GameRes://resource/default.res.json", "GameRes://resource/")');
result = result.replace(/eui\.Theme\("resource\/default\.thm\.json", _this\.stage\)/gm, 'eui.Theme("GameRes://resource/default.thm.json", _this.stage)');
result += ";global.Main = Main;";
file.path = file.dirname + '/main.js'
file.contents = new Buffer(result);
} else if (filename == 'promise.js') {
return null;
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
//同步index.html 配置到main.js
let mainJSPath = path.join(pluginContext.outputDir, 'main.js');
let mainJSContent = fs.readFileSync(mainJSPath, { encoding: "utf8" });
let projectConfig = pluginContext.buildConfig.projectConfig;
mainJSContent = mainJSContent.replace(/frameRate: 30/gm, `frameRate: ${projectConfig.frameRate}`);
mainJSContent = mainJSContent.replace(/contentWidth: 640/gm, `contentWidth: ${projectConfig.contentWidth}`);
mainJSContent = mainJSContent.replace(/contentHeight: 1136/gm, `contentHeight: ${projectConfig.contentHeight}`);
mainJSContent = mainJSContent.replace(/entryClassName: "Main"/gm, `entryClassName: ${projectConfig.entryClassName}`);
mainJSContent = mainJSContent.replace(/scaleMode: "showAll"/gm, `scaleMode: ${projectConfig.scaleMode}`);
mainJSContent = mainJSContent.replace(/orientation: "auto"/gm, `orientation: ${projectConfig.orientation}`);
fs.writeFileSync(mainJSPath, mainJSContent);
}
}
declare var egret;

View File

@@ -0,0 +1,52 @@
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, CleanPlugin } from 'built-in';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_android/assets/game`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new ManifestPlugin({ output: 'manifest.json' })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new UglifyPlugin([{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.json' })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;

View File

@@ -0,0 +1,63 @@
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, CleanPlugin } from 'built-in';
import { BaidugamePlugin } from './baidugame/baidugame';
import { CustomPlugin } from './myplugin';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_baidugame`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new BaidugamePlugin(),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new BaidugamePlugin(),
new UglifyPlugin([
// 使用 EUI 项目,要压缩皮肤文件,可以开启这个压缩配置
// {
// sources: ["resource/default.thm.js"],
// target: "default.thm.min.js"
// },
{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;

View File

@@ -0,0 +1,55 @@
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, CleanPlugin } from 'built-in';
import { BricksPlugin } from './bricks/bricks';
import { CustomPlugin } from './myplugin';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_bricks/PublicBrickEngineGame/Res`;
if (command == 'build') {
return {
outputDir,
commands: [
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new ManifestPlugin({ output: 'manifest.json' }),
new BricksPlugin()
]
}
}
else if (command == 'publish') {
console.log('执行publish')
return {
outputDir,
commands: [
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new ManifestPlugin({ output: 'manifest.json' }),
new UglifyPlugin([{
sources: ["main.js"],
target: "js/main.min.js"
}
]),
new BricksPlugin(),
]
}
} else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;

View File

@@ -0,0 +1,52 @@
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, CleanPlugin } from 'built-in';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_ios/assets/game`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new ManifestPlugin({ output: 'manifest.json' })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new UglifyPlugin([{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.json' })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;

View File

@@ -0,0 +1,63 @@
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, CleanPlugin } from 'built-in';
import { MygamePlugin } from './mygame/mygame';
import { CustomPlugin } from './myplugin';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_mygame`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new MygamePlugin(),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new MygamePlugin(),
new UglifyPlugin([
// 使用 EUI 项目,要压缩皮肤文件,可以开启这个压缩配置
// {
// sources: ["resource/default.thm.js"],
// target: "default.thm.min.js"
// },
{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;

View File

@@ -0,0 +1,62 @@
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, ResSplitPlugin, CleanPlugin } from 'built-in';
import { OppogamePlugin } from './oppogame/oppogame';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_oppogame`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new OppogamePlugin(),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new OppogamePlugin(),
new UglifyPlugin([
// 使用 EUI 项目,要压缩皮肤文件,可以开启这个压缩配置
// {
// sources: ["resource/default.thm.js"],
// target: "default.thm.min.js"
// },
{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;

View File

@@ -0,0 +1,62 @@
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, ResSplitPlugin, CleanPlugin } from 'built-in';
import { MiqgamePlugin } from './qgame/qgame';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_qgame`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new MiqgamePlugin(),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new MiqgamePlugin(),
new UglifyPlugin([
// 使用 EUI 项目,要压缩皮肤文件,可以开启这个压缩配置
// {
// sources: ["resource/default.thm.js"],
// target: "default.thm.min.js"
// },
{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;

View File

@@ -0,0 +1,65 @@
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, CleanPlugin } from 'built-in';
import { QQgamePlugin } from './qqgame/qqgame';
import { CustomPlugin } from './myplugin';
import * as defaultConfig from './config';
//是否使用QQ小游戏引擎插件
const useQQPlugin: boolean = false;
let pluginList: string[] = []
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_qqgame`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new QQgamePlugin(useQQPlugin, pluginList),
new ManifestPlugin({ output: 'manifest.js', qqPlugin: { use: useQQPlugin, pluginList: pluginList } })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new QQgamePlugin(useQQPlugin, pluginList),
new UglifyPlugin([
// 使用 EUI 项目,要压缩皮肤文件,可以开启这个压缩配置
// {
// sources: ["resource/default.thm.js"],
// target: "default.thm.min.js"
// },
{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.js', qqPlugin: { use: useQQPlugin, pluginList: pluginList } })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;

95
demo/scripts/config.ts Normal file
View File

@@ -0,0 +1,95 @@
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, IncrementCompilePlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, RenamePlugin } from 'built-in';
import { WxgamePlugin } from './wxgame/wxgame';
import { BricksPlugin } from './bricks/bricks';
import { CustomPlugin } from './myplugin';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
if (command == 'build') {
const outputDir = '.';
return {
outputDir,
commands: [
// new EmitResConfigFilePlugin({
// output: "resource/default.res.json",
// typeSelector: config.typeSelector,
// nameSelector: p => path.basename(p).replace(/\./gi, "_"),
// groupSelector: p => "preload"
// }),
new ExmlPlugin('debug'), // 非 EUI 项目关闭此设置
new IncrementCompilePlugin(),
]
}
}
else if (command == 'publish') {
const outputDir = `bin-release/web/${version}`;
return {
outputDir,
commands: [
new CustomPlugin(),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new UglifyPlugin([{
sources: ["main.js"],
target: "main.min.js"
}]),
new RenamePlugin({
verbose: true, hash: 'crc32', matchers: [
{ from: "**/*.js", to: "[path][name]_[hash].[ext]" }
]
}),
new ManifestPlugin({ output: "manifest.json" })
]
}
}
else {
throw `unknown command : ${params.command}`
}
},
mergeSelector: (path) => {
if (path.indexOf("assets/bitmap/") >= 0) {
return "assets/bitmap/sheet.sheet"
}
else if (path.indexOf("armature") >= 0 && path.indexOf(".json") >= 0) {
return "assets/armature/1.zip";
}
},
typeSelector: (path) => {
const ext = path.substr(path.lastIndexOf(".") + 1);
const typeMap = {
"jpg": "image",
"png": "image",
"webp": "image",
"json": "json",
"fnt": "font",
"pvr": "pvr",
"mp3": "sound",
"zip": "zip",
"sheet": "sheet",
"exml": "text"
}
let type = typeMap[ext];
if (type == "json") {
if (path.indexOf("sheet") >= 0) {
type = "sheet";
} else if (path.indexOf("movieclip") >= 0) {
type = "movieclip";
};
}
return type;
}
}
export = config;

View File

@@ -0,0 +1,62 @@
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, ResSplitPlugin, CleanPlugin } from 'built-in';
import { VivogamePlugin } from './vivogame/vivogame';
import * as defaultConfig from './config';
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_vivogame/src`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["../engine/js", "resource"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new VivogamePlugin(),
new ManifestPlugin({ output: 'manifest.js', info: { target: 'vivogame' } })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["../engine/js", "resource"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new VivogamePlugin(),
new UglifyPlugin([
// 使用 EUI 项目,要压缩皮肤文件,可以开启这个压缩配置
// {
// sources: ["resource/default.thm.js"],
// target: "default.thm.min.js"
// },
{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.js', info: { target: 'vivogame' } })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;

View File

@@ -0,0 +1,65 @@
/// 阅读 api.d.ts 查看文档
///<reference path="api.d.ts"/>
import * as path from 'path';
import { UglifyPlugin, CompilePlugin, ManifestPlugin, ExmlPlugin, EmitResConfigFilePlugin, TextureMergerPlugin, CleanPlugin } from 'built-in';
import { WxgamePlugin } from './wxgame/wxgame';
import { CustomPlugin } from './myplugin';
import * as defaultConfig from './config';
//是否使用微信分离插件
const useWxPlugin: boolean = false;
const config: ResourceManagerConfig = {
buildConfig: (params) => {
const { target, command, projectName, version } = params;
const outputDir = `../${projectName}_wxgame`;
if (command == 'build') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource", "egret-library"] }),
new CompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new WxgamePlugin(useWxPlugin),
new ManifestPlugin({ output: 'manifest.js' })
]
}
}
else if (command == 'publish') {
return {
outputDir,
commands: [
new CleanPlugin({ matchers: ["js", "resource", "egret-library"] }),
new CompilePlugin({ libraryType: "release", defines: { DEBUG: false, RELEASE: true } }),
new ExmlPlugin('commonjs'), // 非 EUI 项目关闭此设置
new WxgamePlugin(useWxPlugin),
new UglifyPlugin([
// 使用 EUI 项目,要压缩皮肤文件,可以开启这个压缩配置
// {
// sources: ["resource/default.thm.js"],
// target: "default.thm.min.js"
// },
{
sources: ["main.js"],
target: "main.min.js"
}
]),
new ManifestPlugin({ output: 'manifest.js', useWxPlugin: useWxPlugin })
]
}
}
else {
throw `unknown command : ${params.command}`;
}
},
mergeSelector: defaultConfig.mergeSelector,
typeSelector: defaultConfig.typeSelector
}
export = config;

View File

@@ -0,0 +1,82 @@
import * as fs from 'fs';
import * as path from 'path';
export class MygamePlugin implements plugins.Command {
constructor() {
}
async onFile(file: plugins.File) {
if (file.extname == '.js') {
const filename = file.origin;
if (filename == "libs/modules/promise/promise.js" || filename == 'libs/modules/promise/promise.min.js') {
return null;
}
if (filename == 'libs/modules/egret/egret.js' || filename == 'libs/modules/egret/egret.min.js') {
let content = file.contents.toString();
content += `;window.egret = egret;`;
content = content.replace(/definition = __global/, "definition = window");
file.contents = new Buffer(content);
}
else {
let content = file.contents.toString();
if (
filename == "libs/modules/res/res.js" ||
filename == 'libs/modules/res/res.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.js'
) {
content += ";window.RES = RES;"
}
if (filename == "libs/modules/eui/eui.js" || filename == 'libs/modules/eui/eui.min.js') {
content += ";window.eui = eui;"
}
if (filename == 'libs/modules/dragonBones/dragonBones.js' || filename == 'libs/modules/dragonBones/dragonBones.min.js') {
content += ';window.dragonBones = dragonBones';
}
content = "var egret = window.egret;" + content;
if (filename == 'main.js') {
content += "\n;window.Main = Main;"
}
file.contents = new Buffer(content);
}
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
//同步 index.html 配置到 game.js
const gameJSPath = path.join(pluginContext.outputDir, "game.js");
if (!fs.existsSync(gameJSPath)) {
console.log(`${gameJSPath}不存在,请先使用 Launcher 发布支付宝小游戏`);
return;
}
let gameJSContent = fs.readFileSync(gameJSPath, { encoding: "utf8" });
const projectConfig = pluginContext.buildConfig.projectConfig;
const optionStr =
`entryClassName: ${projectConfig.entryClassName},\n\t\t` +
`orientation: ${projectConfig.orientation},\n\t\t` +
`frameRate: ${projectConfig.frameRate},\n\t\t` +
`scaleMode: ${projectConfig.scaleMode},\n\t\t` +
`contentWidth: ${projectConfig.contentWidth},\n\t\t` +
`contentHeight: ${projectConfig.contentHeight},\n\t\t` +
`showFPS: ${projectConfig.showFPS},\n\t\t` +
`fpsStyles: ${projectConfig.fpsStyles},\n\t\t` +
`showLog: ${projectConfig.showLog},\n\t\t` +
`maxTouches: ${projectConfig.maxTouches},`;
const reg = /\/\/----auto option start----[\s\S]*\/\/----auto option end----/;
const replaceStr = '\/\/----auto option start----\n\t\t' + optionStr + '\n\t\t\/\/----auto option end----';
gameJSContent = gameJSContent.replace(reg, replaceStr);
fs.writeFileSync(gameJSPath, gameJSContent);
//修改横竖屏
let orientation;
if (projectConfig.orientation == '"landscape"') {
orientation = "landscape";
}
else {
orientation = "portrait";
}
const gameJSONPath = path.join(pluginContext.outputDir, "game.json");
let gameJSONContent = JSON.parse(fs.readFileSync(gameJSONPath, { encoding: "utf8" }));
gameJSONContent.deviceOrientation = orientation;
fs.writeFileSync(gameJSONPath, JSON.stringify(gameJSONContent, null, "\t"));
}
}

17
demo/scripts/myplugin.ts Normal file
View File

@@ -0,0 +1,17 @@
/**
* 示例自定义插件,您可以查阅 http://developer.egret.com/cn/github/egret-docs/Engine2D/projectConfig/cmdExtensionPlugin/index.html
* 了解如何开发一个自定义插件
*/
export class CustomPlugin implements plugins.Command {
constructor() {
}
async onFile(file: plugins.File) {
return file;
}
async onFinish(commandContext: plugins.CommandContext) {
}
}

4209
demo/scripts/node.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,90 @@
import * as fs from 'fs';
import * as path from 'path';
export class OppogamePlugin implements plugins.Command {
constructor() {
}
async onFile(file: plugins.File) {
if (file.extname == '.js') {
const filename = file.origin;
if (filename == "libs/modules/promise/promise.js" || filename == 'libs/modules/promise/promise.min.js') {
return null;
}
if (filename == 'libs/modules/egret/egret.js' || filename == 'libs/modules/egret/egret.min.js') {
let content = file.contents.toString();
content += `;window.egret = egret;`;
content = content.replace(/definition = __global/, "definition = window");
file.contents = new Buffer(content);
}
else {
let content = file.contents.toString();
if (
filename == "libs/modules/res/res.js" ||
filename == 'libs/modules/res/res.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.js'
) {
content += ";window.RES = RES;"
}
if (filename == "libs/modules/eui/eui.js" || filename == 'libs/modules/eui/eui.min.js') {
content += ";window.eui = eui;"
if(filename == "libs/modules/eui/eui.js"){
content = content.replace("function getRepeatedIds","window.getRepeatedIds=function getRepeatedIds");
content = content.replace("function getIds","window.getIds=function getIds");
content = content.replace("function toXMLString","window.toXMLString=function toXMLString");
content = content.replace("function checkDeclarations","window.checkDeclarations=function checkDeclarations");
content = content.replace("function getPropertyStr","window.getPropertyStr=function getPropertyStr");
}
}
if (filename == 'libs/modules/dragonBones/dragonBones.js' || filename == 'libs/modules/dragonBones/dragonBones.min.js') {
content += ';window.dragonBones = dragonBones';
}
content = "var egret = window.egret;" + content;
if (filename == 'main.js') {
content += "\n;window.Main = Main;"
}
file.contents = new Buffer(content);
}
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
//同步 index.html 配置到 game.js
const gameJSPath = path.join(pluginContext.outputDir, "main.js");
if(!fs.existsSync(gameJSPath)) {
console.log(`${gameJSPath}不存在,请先使用 Launcher 发布Oppo快游戏`);
return;
}
let gameJSContent = fs.readFileSync(gameJSPath, { encoding: "utf8" });
const projectConfig = pluginContext.buildConfig.projectConfig;
const optionStr =
`entryClassName: ${projectConfig.entryClassName},\n\t\t` +
`orientation: ${projectConfig.orientation},\n\t\t` +
`frameRate: ${projectConfig.frameRate},\n\t\t` +
`scaleMode: ${projectConfig.scaleMode},\n\t\t` +
`contentWidth: ${projectConfig.contentWidth},\n\t\t` +
`contentHeight: ${projectConfig.contentHeight},\n\t\t` +
`showFPS: ${projectConfig.showFPS},\n\t\t` +
`fpsStyles: ${projectConfig.fpsStyles},\n\t\t` +
`showLog: ${projectConfig.showLog},\n\t\t` +
`maxTouches: ${projectConfig.maxTouches},`;
const reg = /\/\/----auto option start----[\s\S]*\/\/----auto option end----/;
const replaceStr = '\/\/----auto option start----\n\t\t' + optionStr + '\n\t\t\/\/----auto option end----';
gameJSContent = gameJSContent.replace(reg, replaceStr);
fs.writeFileSync(gameJSPath, gameJSContent);
//修改横竖屏
let orientation;
if (projectConfig.orientation == '"landscape"') {
orientation = "landscape";
}
else {
orientation = "portrait";
}
const gameJSONPath = path.join(pluginContext.outputDir, "manifest.json");
let gameJSONContent = JSON.parse(fs.readFileSync(gameJSONPath, { encoding: "utf8" }));
gameJSONContent.orientation = orientation;
fs.writeFileSync(gameJSONPath, JSON.stringify(gameJSONContent, null, "\t"));
}
}

View File

@@ -0,0 +1,90 @@
import * as fs from 'fs';
import * as path from 'path';
export class MiqgamePlugin implements plugins.Command {
constructor() {
}
async onFile(file: plugins.File) {
if (file.extname == '.js') {
const filename = file.origin;
if (filename == "libs/modules/promise/promise.js" || filename == 'libs/modules/promise/promise.min.js') {
return null;
}
if (filename == 'libs/modules/egret/egret.js' || filename == 'libs/modules/egret/egret.min.js') {
let content = file.contents.toString();
content += `;window.egret = egret;`;
content = content.replace(/definition = __global/, "definition = window");
file.contents = new Buffer(content);
}
else {
let content = file.contents.toString();
if (
filename == "libs/modules/res/res.js" ||
filename == 'libs/modules/res/res.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.js'
) {
content += ";window.RES = RES;"
}
if (filename == "libs/modules/eui/eui.js" || filename == 'libs/modules/eui/eui.min.js') {
content += ";window.eui = eui;"
if(filename == "libs/modules/eui/eui.js"){
content = content.replace("function getRepeatedIds","window.getRepeatedIds=function getRepeatedIds");
content = content.replace("function getIds","window.getIds=function getIds");
content = content.replace("function toXMLString","window.toXMLString=function toXMLString");
content = content.replace("function checkDeclarations","window.checkDeclarations=function checkDeclarations");
content = content.replace("function getPropertyStr","window.getPropertyStr=function getPropertyStr");
}
}
if (filename == 'libs/modules/dragonBones/dragonBones.js' || filename == 'libs/modules/dragonBones/dragonBones.min.js') {
content += ';window.dragonBones = dragonBones';
}
content = "var egret = window.egret;" + content;
if (filename == 'main.js') {
content += "\n;window.Main = Main;"
}
file.contents = new Buffer(content);
}
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
//同步 index.html 配置到 game.js
const gameJSPath = path.join(pluginContext.outputDir, "main.js");
if(!fs.existsSync(gameJSPath)) {
console.log(`${gameJSPath}不存在,请先使用 Launcher 发布小米快游戏`);
return;
}
let gameJSContent = fs.readFileSync(gameJSPath, { encoding: "utf8" });
const projectConfig = pluginContext.buildConfig.projectConfig;
const optionStr =
`entryClassName: ${projectConfig.entryClassName},\n\t\t` +
`orientation: ${projectConfig.orientation},\n\t\t` +
`frameRate: ${projectConfig.frameRate},\n\t\t` +
`scaleMode: ${projectConfig.scaleMode},\n\t\t` +
`contentWidth: ${projectConfig.contentWidth},\n\t\t` +
`contentHeight: ${projectConfig.contentHeight},\n\t\t` +
`showFPS: ${projectConfig.showFPS},\n\t\t` +
`fpsStyles: ${projectConfig.fpsStyles},\n\t\t` +
`showLog: ${projectConfig.showLog},\n\t\t` +
`maxTouches: ${projectConfig.maxTouches},`;
const reg = /\/\/----auto option start----[\s\S]*\/\/----auto option end----/;
const replaceStr = '\/\/----auto option start----\n\t\t' + optionStr + '\n\t\t\/\/----auto option end----';
gameJSContent = gameJSContent.replace(reg, replaceStr);
fs.writeFileSync(gameJSPath, gameJSContent);
//修改横竖屏
let orientation;
if (projectConfig.orientation == '"landscape"') {
orientation = "landscape";
}
else {
orientation = "portrait";
}
const gameJSONPath = path.join(pluginContext.outputDir, "manifest.json");
let gameJSONContent = JSON.parse(fs.readFileSync(gameJSONPath, { encoding: "utf8" }));
gameJSONContent.orientation = orientation;
fs.writeFileSync(gameJSONPath, JSON.stringify(gameJSONContent, null, "\t"));
}
}

View File

@@ -0,0 +1,118 @@
import * as fs from 'fs';
import * as path from 'path';
export class QQgamePlugin implements plugins.Command {
private useQQPlugin: boolean = false;
private pliginList: string[] = [];//qq engine plugin
constructor(useQQPlugin: boolean, pliginList: string[]) {
this.useQQPlugin = useQQPlugin
this.pliginList = pliginList
}
async onFile(file: plugins.File) {
if (file.extname == '.js') {
const filename = file.origin;
if (filename == "libs/modules/promise/promise.js" || filename == 'libs/modules/promise/promise.min.js') {
return null;
}
if (this.useQQPlugin) {
const basename = file.basename
//QQ 小游戏引擎插件,支持下列官方库
let engineJS = ['assetsmanager', 'dragonBones', 'egret', 'game', 'eui', 'socket', 'tween']
for (let i in engineJS) {
let jsName = engineJS[i]
if (basename == jsName + ".js" || basename == jsName + ".min.js") {
this.pliginList.push(`requirePlugin("egret-library/${jsName}.min.js")`);
return null
}
}
}
if (filename == 'libs/modules/egret/egret.js' || filename == 'libs/modules/egret/egret.min.js') {
let content = file.contents.toString();
content += `;window.egret = egret;`;
content = content.replace(/definition = __global/, "definition = window");
file.contents = new Buffer(content);
}
else {
let content = file.contents.toString();
if (
filename == "libs/modules/res/res.js" ||
filename == 'libs/modules/res/res.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.js'
) {
content += ";window.RES = RES;"
}
if (filename == "libs/modules/eui/eui.js" || filename == 'libs/modules/eui/eui.min.js') {
content += ";window.eui = eui;"
}
if (filename == 'libs/modules/dragonBones/dragonBones.js' || filename == 'libs/modules/dragonBones/dragonBones.min.js') {
content += ';window.dragonBones = dragonBones';
}
content = "var egret = window.egret;" + content;
if (filename == 'main.js') {
content += "\n;window.Main = Main;"
}
file.contents = new Buffer(content);
}
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
let { projectRoot, outputDir, buildConfig } = pluginContext
//同步 index.html 配置到 game.js
const gameJSPath = path.join(outputDir, "game.js");
if (!fs.existsSync(gameJSPath)) {
console.log(`${gameJSPath}不存在,请先使用 Launcher 发布QQ小游戏`);
return;
}
let gameJSContent = fs.readFileSync(gameJSPath, { encoding: "utf8" });
const projectConfig = buildConfig.projectConfig;
const optionStr =
`entryClassName: ${projectConfig.entryClassName},\n\t\t` +
`orientation: ${projectConfig.orientation},\n\t\t` +
`frameRate: ${projectConfig.frameRate},\n\t\t` +
`scaleMode: ${projectConfig.scaleMode},\n\t\t` +
`contentWidth: ${projectConfig.contentWidth},\n\t\t` +
`contentHeight: ${projectConfig.contentHeight},\n\t\t` +
`showFPS: ${projectConfig.showFPS},\n\t\t` +
`fpsStyles: ${projectConfig.fpsStyles},\n\t\t` +
`showLog: ${projectConfig.showLog},\n\t\t` +
`maxTouches: ${projectConfig.maxTouches},`;
const reg = /\/\/----auto option start----[\s\S]*\/\/----auto option end----/;
const replaceStr = '\/\/----auto option start----\n\t\t' + optionStr + '\n\t\t\/\/----auto option end----';
gameJSContent = gameJSContent.replace(reg, replaceStr);
fs.writeFileSync(gameJSPath, gameJSContent);
//修改横竖屏
let orientation;
if (projectConfig.orientation == '"landscape"') {
orientation = "landscape";
}
else {
orientation = "portrait";
}
const gameJSONPath = path.join(outputDir, "game.json");
let gameJSONContent = this.readData(gameJSONPath);
gameJSONContent.deviceOrientation = orientation;
if (!gameJSONContent.plugins) {
gameJSONContent.plugins = {}
}
if (!this.useQQPlugin) {
delete gameJSONContent.plugins["egret-library"]
} else {
let engineVersion = this.readData(path.join(projectRoot, "egretProperties.json")).engineVersion;
gameJSONContent.plugins["egret-library"] = {
"provider": "1110108620",
"version": engineVersion
}
}
this.writeData(gameJSONContent, gameJSONPath)
}
readData(filePath: string): any {
return JSON.parse(fs.readFileSync(filePath, { encoding: "utf8" }));
}
writeData(data: object, filePath: string) {
fs.writeFileSync(filePath, JSON.stringify(data, null, "\t"));
}
}

View File

@@ -0,0 +1,50 @@
{
"compilerOptions": {
/* Basic Options */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */
"lib": [
"es5",
"es2015.promise"
], /* Specify library files to be included in the compilation: */
"allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
// "outDir": "./", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": false /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
/* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
/* Source Map Options */
// "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
}
}

View File

@@ -0,0 +1,126 @@
import * as fs from 'fs';
import * as path from 'path';
export class VivogamePlugin implements plugins.Command {
jsFileList: any = []
constructor() {
}
async onFile(file: plugins.File) {
if (file.extname == '.js') {
const filename = file.origin;
if (filename == "libs/modules/promise/promise.js" || filename == 'libs/modules/promise/promise.min.js') {
return null;
}
this.jsFileList.push(file.basename)
if (filename == 'libs/modules/egret/egret.js' || filename == 'libs/modules/egret/egret.min.js') {
let content = file.contents.toString();
content += `;window.egret = egret;`;
content = content.replace(/definition = __global/, "definition = window");
file.contents = new Buffer(content);
}
else {
let content = file.contents.toString();
if (
filename == "libs/modules/res/res.js" ||
filename == 'libs/modules/res/res.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.js'
) {
content += ";window.RES = RES;"
}
if (filename == "libs/modules/eui/eui.js" || filename == 'libs/modules/eui/eui.min.js') {
content += ";window.eui = eui;"
if (filename == "libs/modules/eui/eui.js") {
content = content.replace("function getRepeatedIds", "window.getRepeatedIds=function getRepeatedIds");
content = content.replace("function getIds", "window.getIds=function getIds");
content = content.replace("function toXMLString", "window.toXMLString=function toXMLString");
content = content.replace("function checkDeclarations", "window.checkDeclarations=function checkDeclarations");
content = content.replace("function getPropertyStr", "window.getPropertyStr=function getPropertyStr");
}
}
if (filename == 'libs/modules/dragonBones/dragonBones.js' || filename == 'libs/modules/dragonBones/dragonBones.min.js') {
content += ';window.dragonBones = dragonBones';
}
content = "var egret = window.egret;" + content;
if (filename == 'main.js') {
content += "\n;window.Main = Main;"
}
file.contents = new Buffer(content);
}
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
//同步 index.html 配置到 game.js
const gameJSPath = path.join(pluginContext.outputDir, "game.js");
if (!fs.existsSync(gameJSPath)) {
console.log(`${gameJSPath}不存在,请先使用 Launcher 发布 Vivo 小游戏`);
return;
}
let gameJSContent = fs.readFileSync(gameJSPath, { encoding: "utf8" });
const projectConfig = pluginContext.buildConfig.projectConfig;
const optionStr =
`entryClassName: ${projectConfig.entryClassName},\n\t\t` +
`orientation: ${projectConfig.orientation},\n\t\t` +
`frameRate: ${projectConfig.frameRate},\n\t\t` +
`scaleMode: ${projectConfig.scaleMode},\n\t\t` +
`contentWidth: ${projectConfig.contentWidth},\n\t\t` +
`contentHeight: ${projectConfig.contentHeight},\n\t\t` +
`showFPS: ${projectConfig.showFPS},\n\t\t` +
`fpsStyles: ${projectConfig.fpsStyles},\n\t\t` +
`showLog: ${projectConfig.showLog},\n\t\t` +
`maxTouches: ${projectConfig.maxTouches},`;
const reg = /\/\/----auto option start----[\s\S]*\/\/----auto option end----/;
const replaceStr = '\/\/----auto option start----\n\t\t' + optionStr + '\n\t\t\/\/----auto option end----';
gameJSContent = gameJSContent.replace(reg, replaceStr);
fs.writeFileSync(gameJSPath, gameJSContent);
//修改横竖屏
let orientation;
if (projectConfig.orientation == '"landscape"') {
orientation = "landscape";
}
else {
orientation = "portrait";
}
const gameJSONPath = path.join(pluginContext.outputDir, "manifest.json");
let gameJSONContent = JSON.parse(fs.readFileSync(gameJSONPath, { encoding: "utf8" }));
gameJSONContent.deviceOrientation = orientation;
let engineVersion = this.readData(path.join(pluginContext.projectRoot, "egretProperties.json")).engineVersion
if(!gameJSONContent.thirdEngine)gameJSONContent.thirdEngine={}
gameJSONContent.thirdEngine.egret = engineVersion
fs.writeFileSync(gameJSONPath, JSON.stringify(gameJSONContent, null, "\t"));
let isPublish = pluginContext.buildConfig.command == "publish" ? true : false;
let configArr: any[] = []
for (var i = 0, len = this.jsFileList.length; i < len; i++) {
let jsFile = this.jsFileList[i];
if (isPublish) {
if (jsFile == "main.js") {
jsFile = 'main.min.js'
} else if (jsFile == "default.thm.js") {
jsFile = "default.thm.min.js"
}
}
configArr.push(JSON.stringify({
module_name: `./js/${jsFile}`,
module_path: `./js/${jsFile}`,
module_from: `engine/js/${jsFile}`,
}, null, "\t"))
}
const replaceConfigStr = '\/\/----auto option start----\n\t\t' + configArr.toString() + '\n\t\t\/\/----auto option end----';
const minigameConfigPath = path.join(pluginContext.outputDir,"../", "minigame.config.js");
if(!fs.existsSync(minigameConfigPath)){
//5.2.28版本vivo更新了项目结构老项目需要升级
fs.writeFileSync(path.join(pluginContext.outputDir,"../","vivo更新了项目结构请重新创建vivo小游戏项目.js"), "vivo更新了项目结构请重新创建vivo小游戏项目");
}else{
let configJSContent = fs.readFileSync(minigameConfigPath, { encoding: "utf8" });
configJSContent = configJSContent.replace(reg, replaceConfigStr);
fs.writeFileSync(minigameConfigPath, configJSContent);
}
}
readData(filePath: string): any {
return JSON.parse(fs.readFileSync(filePath, { encoding: "utf8" }));
}
}

View File

@@ -0,0 +1,146 @@
import * as fs from 'fs';
import * as path from 'path';
const crypto = require('crypto');
export class WxgamePlugin implements plugins.Command {
private useWxPlugin:boolean = false;
constructor(useWxPlugin:boolean) {
this.useWxPlugin = useWxPlugin
}
md5Obj = {}
md5(content) {
let md5 = crypto.createHash('md5');
return md5.update(content).digest('hex');
}
async onFile(file: plugins.File) {
if (file.extname == '.js') {
const filename = file.origin;
if (filename == "libs/modules/promise/promise.js" || filename == 'libs/modules/promise/promise.min.js') {
return null;
}
if (filename == 'libs/modules/egret/egret.js' || filename == 'libs/modules/egret/egret.min.js') {
let content = file.contents.toString();
content += `;window.egret = egret;`;
content = content.replace(/definition = __global/, "definition = window");
this.md5Obj[path.basename(filename)] = this.md5(content)
file.contents = new Buffer(content);
}
else {
let content = file.contents.toString();
if (
filename == "libs/modules/res/res.js" ||
filename == 'libs/modules/res/res.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.min.js' ||
filename == 'libs/modules/assetsmanager/assetsmanager.js'
) {
content += ";window.RES = RES;"
}
if (filename == "libs/modules/eui/eui.js" || filename == 'libs/modules/eui/eui.min.js') {
content += ";window.eui = eui;"
}
if (filename == 'libs/modules/dragonBones/dragonBones.js' || filename == 'libs/modules/dragonBones/dragonBones.min.js') {
content += ';window.dragonBones = dragonBones';
}
content = "var egret = window.egret;" + content;
if (filename == 'main.js') {
content += "\n;window.Main = Main;"
}
this.md5Obj[path.basename(filename)] = this.md5(content)
file.contents = new Buffer(content);
}
}
return file;
}
async onFinish(pluginContext: plugins.CommandContext) {
let { projectRoot, outputDir, buildConfig } = pluginContext
//同步 index.html 配置到 game.js
const gameJSPath = path.join(outputDir, "game.js");
if (!fs.existsSync(gameJSPath)) {
console.log(`${gameJSPath}不存在,请先使用 Launcher 发布微信小游戏`);
return;
}
let gameJSContent = fs.readFileSync(gameJSPath, { encoding: "utf8" });
const projectConfig = buildConfig.projectConfig;
const optionStr =
`entryClassName: ${projectConfig.entryClassName},\n\t\t` +
`orientation: ${projectConfig.orientation},\n\t\t` +
`frameRate: ${projectConfig.frameRate},\n\t\t` +
`scaleMode: ${projectConfig.scaleMode},\n\t\t` +
`contentWidth: ${projectConfig.contentWidth},\n\t\t` +
`contentHeight: ${projectConfig.contentHeight},\n\t\t` +
`showFPS: ${projectConfig.showFPS},\n\t\t` +
`fpsStyles: ${projectConfig.fpsStyles},\n\t\t` +
`showLog: ${projectConfig.showLog},\n\t\t` +
`maxTouches: ${projectConfig.maxTouches},`;
const reg = /\/\/----auto option start----[\s\S]*\/\/----auto option end----/;
const replaceStr = '\/\/----auto option start----\n\t\t' + optionStr + '\n\t\t\/\/----auto option end----';
gameJSContent = gameJSContent.replace(reg, replaceStr);
fs.writeFileSync(gameJSPath, gameJSContent);
//修改横竖屏
let orientation;
if (projectConfig.orientation == '"landscape"') {
orientation = "landscape";
}
else {
orientation = "portrait";
}
const gameJSONPath = path.join(outputDir, "game.json");
let gameJSONContent = this.readData(gameJSONPath)
gameJSONContent.deviceOrientation = orientation;
if (buildConfig.command !== "publish" && gameJSONContent.plugins && gameJSONContent.plugins['egret-library']) {
delete gameJSONContent.plugins["egret-library"]
}
this.writeData(gameJSONContent, gameJSONPath)
//下面的流程是配置开启微信插件的功能
let engineVersion = this.readData(path.join(projectRoot, "egretProperties.json")).engineVersion;
if (!gameJSONContent.plugins) {
gameJSONContent.plugins = {}
}
if(buildConfig.command == "publish" && this.useWxPlugin){
gameJSONContent.plugins["egret-library"] = {
"provider": "wx7e2186943221985d",
"version": engineVersion,
"path": "egret-library"
}
}else{
gameJSONContent.plugins = {}
}
this.writeData(gameJSONContent, gameJSONPath)
if (buildConfig.command !== "publish" || !this.useWxPlugin) {
return
}
let libDir = path.join(outputDir, "egret-library")
fs.mkdirSync(libDir)
let pluginData = { "main": "index.js" }
this.writeData(pluginData, path.join(libDir, "plugin.json"))
let engineJS = ['assetsmanager', 'dragonBones', 'egret', 'game', 'eui', 'socket', 'tween']
let signatureData: any = {
"provider": "wx7e2186943221985d",
"signature": []
}
for (let i in engineJS) {
let name = engineJS[i] + '.min.js'
if (this.md5Obj[name]) {
let jsInfo: any = {
"path": name,
"md5": this.md5Obj[name]
}
signatureData.signature.push(jsInfo)
}
}
this.writeData(signatureData, path.join(libDir, "signature.json"))
fs.writeFileSync(path.join(libDir, "index.js"), null);
}
readData(filePath: string): any {
return JSON.parse(fs.readFileSync(filePath, { encoding: "utf8" }));
}
writeData(data: object, filePath: string) {
fs.writeFileSync(filePath, JSON.stringify(data, null, "\t"));
}
}