123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- /*
- 面板扩展
- 功能: 监听 creator项目下 node_modules 目录与加载
- */
- 'use strict';
- const path = require('path');
- const fs = require('fs');
- const tools = require('../../tools/tools');
- const prsPath = Editor.Project && Editor.Project.path ? Editor.Project.path : Editor.remote.projectPath;
- const node_modules_path = path.join(prsPath,'node_modules');
- const REG_EXP_MULTILAYER = /node_modules/g
- const REG_EXP_JSON_CONFIG = /(tsconfig.*\.json|jsconfig.*\.json|package\.json)/;
- const REG_EXP_TS_CONFIG = /(tsconfig.*\.json|jsconfig.*\.json)/;
- const REG_EXP_PACKAGE = /(package\.json)/
- module.exports = {
- /** @type import('../../panel/vs-panel/vs-panel-base') */
- parent : null,
- // 初始化事件
- onLoadEvent(parent){
- // index.js 对象
- this.parent = parent;
- this.dependencies = {};
- // 创建view缓存model事件
- this.parent.monaco.editor.onDidCreateModel((model)=>
- {
- // 加载 tsconfig 配置文件解析
- let url = model.uri.toString();
- if(url.match(REG_EXP_TS_CONFIG) && this.isDependencie(url)){
- this.parent.tsWr.addProjectReference(url)
- setTimeout(()=>this.parent.tsWr.writeOtherFile(url,model.getValue()),1);
- }else{
- this.updatePackageMainModulePath(model)
- }
- });
- // 删除代码文件 view缓存model
- this.parent.monaco.editor.onWillDisposeModel((model)=>{
- // 删除 tsconfig 配置文件解析
- let url = model.uri.toString();
- let isconfig = url.match(REG_EXP_TS_CONFIG);
- if(isconfig){
- this.parent.tsWr.removeProjectReference(url)
- }
- if(isconfig || url.endsWith('package.json')){
- setTimeout(()=>this.parent.tsWr.removeOtherFile(url),1);
- }
- });
- this.initProjectConfig()
- },
- // 加载creator游戏脚本package.json、tsconfig.json配置
- initProjectConfig()
- {
- // 加载、监听tsconfig项目配置变动
- let tsconfigPath = path.join(prsPath,'tsconfig.json');
- this.watchFile = this.parent.fileMgr.addWatchPath(tsconfigPath,this.onFileStatChange.bind(this))
- // 必须先加载package项目配置
- let packagePath = path.join(prsPath,'package.json');
- if(tools.isFileExit(packagePath)){
- let jsonText = fs.readFileSync(packagePath).toString()
- this.updateProjectPackage(jsonText)
- }
- // 监听package项目配置变动
- this.parent.fileMgr.addWatchPath(packagePath,(eventName,files)=>{
- if (eventName == "create" || eventName == 'change') {
- if(tools.isFileExit(packagePath)){
- let jsonText = fs.readFileSync(packagePath).toString()
- this.updateProjectPackage(jsonText,true)
- }
- }
- this.onFileStatChange(eventName,files);
- })
- },
- // 设置选项
- setOptions(cfg,isInit)
- { if(cfg.enabledNpmDir == null) return;
-
- if(cfg.enabledNpmDir){
- if(!isInit){
- return Editor.log("加载node_modules设置 重启creator后生效")
- }
- this.initWatch()
- }else if(!cfg.enabledNpmDir && this._isInit)
- {
- this.stop()
- }
- },
- // 初始化 node_modules 文件夹监听
- initWatch(){
- delete this.check_timeout;
- this._isInit = true;
- this.watchFile = this.parent.fileMgr.addWatchPath(node_modules_path,this.onFileStatChange.bind(this))
- },
-
- // node_modules文件变化监听
- onFileStatChange(eventName,files){
- if (eventName == "init" || eventName == "create") {
- // Finished walking the tree
- this.addNodeModuleFiles(files);
- }else if (eventName == 'change') {
- this.changeNodeModuleFiles(files);
- }else if (eventName == 'delete') {
- this.unlinkNodeModuleFiles(files);
- }
- },
- // 读取项目package文件信息
- updateProjectPackage(text,isLoadDependenciesFiles=false){
- let packageContent = tools.parseJson(text);
- if(packageContent == null){
- return;
- }
- // 依赖包加载,用于代码提示自动导入路径
- this.dependencies = Object.assign(
- {},
- packageContent.dependencies,
- packageContent.devDependencies,
- packageContent.peerDependencies,
- packageContent.bundledDependencies,
- packageContent.optionalDependencies,
- );
- // 加载依赖模块文件
- if(isLoadDependenciesFiles){
- for (const key in this.dependencies) {
- let packagePath = path.join(node_modules_path,key,'package.json');
- packagePath = packagePath.replace(/\\/g,'/')
- if(tools.isFileExit(packagePath)){
- let packageModel = this.parent.loadVsModel(packagePath,path.extname(packagePath),false);
- this.updatePackageMainModulePath(packageModel);
- };
- }
- }
- },
- // 系统文件保存修改内容
- onAssetsChangedEvent(file){
- let fspath = file.uuid == 'outside' ? file.url : Editor.remote.assetdb.uuidToFspath(file.uuid);
- if(fspath.match(REG_EXP_JSON_CONFIG)){
- let vs_model = this.parent.fileMgr.getModelByFsPath(fspath);
- if(vs_model && this.isDependencie(vs_model.uri.toString())){
- this.parent.tsWr.writeOtherFile(vs_model.uri.toString(),vs_model.getValue());
- }
- }
- },
- // 刷新并导入并模块入口文件
- updatePackageMainModulePath(model){
- let url = model.uri.toString();
- if(!url.match(REG_EXP_PACKAGE) || !this.isDependencie(url)){
- return;
- }
-
- setTimeout(async ()=>{
- this.parent.tsWr.writeOtherFile(url,model.getValue()); // 保存package.json文件缓存到ts解析器参与进一步解析工作
- let tryModulePaths = await this.parent.tsWr.getPackageMainModulePath(url);
- // console.log("modeule包路径:",url,tryModulePaths)
- let filePath = await this.parent.fileMgr.loadNeedImportPathsAsync({[url]:tryModulePaths});
- if(filePath){
- // 性能优化: 忽略模块文件import路径深度解析功能
- this.parent.tsWr.setIgnoreTryImportScriptFile(this.parent.fileMgr.fsPathToModelUrl(filePath));
- }
- },1)
- },
- // 是否项目依赖的包
- isDependencie(url){
- let split = url.split('node_modules')
- let modulePath = split[1];
- if(!modulePath || tools.objectCount(this.dependencies) == 0){
- return true;
- }
- let dir = path.dirname(modulePath);
- dir = dir.substr(1);
- for (const key in this.dependencies) {
- if(key == dir){
- return true;
- }
- }
- return false;
- },
- // 多层 node_modules 目录
- isMultilayerNodeModuleDir(filePath){
- let reg = filePath.match(REG_EXP_MULTILAYER);
- return reg && reg.length>1;
- },
- isNodeModuleDir(path){
- return path && path.indexOf(node_modules_path) != -1;
- },
- addNodeModuleFiles(files){
- let c_files = []
- for (let k in files) {
- let filePath = files[k]
- if(!this.isMultilayerNodeModuleDir(filePath) && !filePath.endsWith('.DS_Store')){
- filePath = filePath.replace(/\\/g,'/');
- if(!this.parent.file_list_map[filePath]){
- c_files.push({
- url : filePath,
- uuid: 'outside'
- })
- }
- }
- }
- this.parent.messages['asset-db:assets-created'].bind(this.parent)(0,c_files)
- },
- // 改变文件
- changeNodeModuleFiles(files){
- let c_files = []
- for (let k in files) {
- let filePath = files[k];
- if(!this.isMultilayerNodeModuleDir(filePath) && !filePath.endsWith('.DS_Store')){
- filePath = filePath.replace(/\\/g,'/');
- if(!this.parent.file_list_map[filePath]){
- c_files.push({
- url : filePath,
- uuid: 'outside'
- })
- }
- }
- }
- for (let i = 0; i < c_files.length; i++) {
- const element = c_files[i];
- this.parent.messages['asset-db:asset-changed'].bind(this.parent)(0,element)
- }
- },
- // 移除文件
- unlinkNodeModuleFiles(files){
- let removeFiles = []
- for (let k in files) {
- let filePath = files[k]
- if(!this.isMultilayerNodeModuleDir(filePath) && !filePath.endsWith('.DS_Store')){
- filePath = filePath.replace(/\\/g,'/');
- if(this.parent.file_list_map[filePath]){
- removeFiles.push({
- url : filePath,
- path : filePath,
- uuid: 'outside'
- })
- }
- }
- }
- // console.log('移除文件夹:',removeFiles)
- this.parent.messages['asset-db:assets-deleted'].bind(this.parent)(0,removeFiles)
- },
- stop(){
- if(this.watchFile){
- this.watchFile.stop()
- this.watchFile = null;
- }
- if(this.check_timeout){
- clearTimeout(this.check_timeout);
- delete this.check_timeout;
- }
- },
- // 面板销毁
- onDestroy(){
- this.stop()
- },
- /************* 事件 *************/
- messages:{
- 'scene:saved'(){
- }
- },
-
- };
|