Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Screeps:如何使用TypeScript和Webpack设置源地图?_Typescript_Webpack_Source Maps_Screeps - Fatal编程技术网

Screeps:如何使用TypeScript和Webpack设置源地图?

Screeps:如何使用TypeScript和Webpack设置源地图?,typescript,webpack,source-maps,screeps,Typescript,Webpack,Source Maps,Screeps,我正在尝试使用TypeScript(^2.9.2)和Webpack(^4.12.1)从头开始设置新的Screeps(游戏)项目。如何正确设置源地图?我所做的: 在tsconfig.json中设置“sourceMap”:true, 在webpack.config.js中设置devtool:“内联源代码映射”。我想内联是尖叫的必要条件 设置loader:test:/\.ts$/,的loader:,在网页包配置中强制执行:'pre',,以避免丢失ts源地图 在我的main.ts中,它现在只是conso

我正在尝试使用TypeScript(^2.9.2)和Webpack(^4.12.1)从头开始设置新的Screeps(游戏)项目。如何正确设置源地图?我所做的:

  • 在tsconfig.json中设置
    “sourceMap”:true,
  • 在webpack.config.js中设置
    devtool:“内联源代码映射”
    。我想内联是尖叫的必要条件
  • 设置
    loader:
    test:/\.ts$/,
    loader:
    ,在网页包配置中强制执行:'pre',
    ,以避免丢失ts源地图
  • 在我的main.ts中,它现在只是
    console.log(foo)结果为:

    ReferenceError: foo is not defined
        at Object../src/main.ts:98:13
        at __webpack_require__:20:30
        at eval:84:18
        at main:87:10
        at eval:105:4
        at Object.<anonymous>:2:143759
        at Object.r.run:2:144268```
    

    唷,我成功了。以下是需要做的事情:

  • 在网页包配置中:

    • 将目标设置为“节点”

      config.target = 'node';
      
    • 将输出库目标设置为
      commonjs2

      config.output.libraryTarget = 'commonjs2';
      
    • 设置您的常规devtool

      config.devtool = 'source-map';
      
      内联源映射在Screeps中不起作用

    • 设置外部

      config.externals = {
        'main.js.map': 'main.js.map',
      };
      
    这样我们就可以在代码中编写
    require('main.js.map')
    ,以便在Screeps运行时加载源映射文件,这样Webpack就不用管它了

  • 在tsconfig.json中设置
    config.compilerOptions.sourceMap
    true

  • 将代码上载到Screeps服务器:

    • 像往常一样上传你的
      main.js
      bundle文件
    • 上传你的源地图文件。将其命名为
      main.js.map.js
      。最后一个
      .js
      很重要-Screeps游戏会将其切断,留下所需的
      main.js.map
  • 在运行时自己解析源映射

    • 添加源映射
      /
      npm-i源映射--保存
    • 将其保留为版本^0.6.1^0.7(目前最新版本)仅为异步。异步代码在Screeps中不起作用
    • 使用它手动生成stacktrace消息错误。然后使用
      console.log()
      打印它
    • 是的,这需要游戏中的CPU。缓存错误消息,以便在遇到新错误时只解析一次,而不是每次都解析一次
    • 另外,源映射在模拟模式下也不起作用(我希望知道得更快)
  • 围绕错误映射器包装您的代码:

    export const loop = () => {
      errorMapper(tick)();
    };
    
    const tick = () => { /* your regular code for current tick */};
    
  • 祝您调试顺利


  • 实际上,这是我的error-mapper.ts:

    import { escape } from 'lodash';
    import { MappedPosition, SourceMapConsumer } from 'source-map'; // leave it at version ^0.6.1. ^0.7 is async only.
    
    export default function errorMapper(tick: () => void): () => void {
        return () => {
            try {
                tick();
            } catch (error) {
                if (error instanceof Error) {
                    const isSimulation: boolean = ('sim' in Game.rooms);
                    if (isSimulation) {
                        printOriginalError(error);
                    } else {
                        printStackTrace(error);
                    }
                } else {
                    throw error;
                }
            }
        };
    }
    
    // tslint:disable-next-line: no-var-requires
    const consumer: SourceMapConsumer = new SourceMapConsumer(require('main.js.map')); // High CPU usage!
    const cache: { [key: string]: string } = {};
    
    function getSourceMapStackTrace(error: Error | string): string {
        const originalStackTrace: string = error instanceof Error ? error.stack as string : error;
        if (cache[originalStackTrace]) {
            return cache[originalStackTrace];
        }
    
        const re = /^\s+at\s+(.+?\s+)?\(?([0-z._\-\\\/]+):(\d+):(\d+)\)?$/gm;
        let match: RegExpExecArray | null;
        let outputStackTrace: string = error.toString();
    
        // tslint:disable-next-line:no-conditional-assignment
        while ((match = re.exec(originalStackTrace)) !== null) {
            const nameFromOriginalStackTrace: string = match[1];
            const isStackTraceLineControlledByMe: boolean = match[2] === 'main';
            const lineFromOriginalStackTrace: number = parseInt(match[3], 10);
            const columnFromOriginalStackTrace: number = parseInt(match[4], 10);
    
            if (!isStackTraceLineControlledByMe) {
                break;
            }
    
            const { name, source, line, column }: MappedPosition = consumer.originalPositionFor({
                column: columnFromOriginalStackTrace,
                line: lineFromOriginalStackTrace,
            });
    
            if (!line) {
                break;
            }
    
            const finalName = (name) ? name : (nameFromOriginalStackTrace) ? nameFromOriginalStackTrace : '';
    
            outputStackTrace += stripWebpackFromStackTrace(
                `\n    at ${finalName}(${source}:${line}:${column})`,
            );
        }
    
        cache[originalStackTrace] = outputStackTrace;
        return outputStackTrace;
    }
    
    function printOriginalError(error: Error) {
        const message = `Source maps don't work in the Simulation mode.`;
        console.log(`<span style="color: tomato">${message}\n${escape(error.stack)}</span>`);
    }
    
    function printStackTrace(error: Error) {
        const errorMessage = escape(getSourceMapStackTrace(error));
        console.log(`<span style="color: tomato">${errorMessage}</span>`);
        Game.notify(errorMessage);
    }
    
    function stripWebpackFromStackTrace(text: string): string {
        return text.replace('webpack:///', '');
    }
    
    从'lodash'导入{escape};
    从“源映射”导入{MappedPosition,SourceMapConsumer};//将其保留为版本^0.6.1^0.7只是异步的。
    导出默认函数errorMapper(勾选:()=>void):()=>void{
    return()=>{
    试一试{
    勾选();
    }捕获(错误){
    if(错误实例of error){
    const-isSimulation:boolean=('sim'在Game.rooms中);
    如果(模拟){
    打印原件错误(错误);
    }否则{
    printStackTrace(错误);
    }
    }否则{
    投掷误差;
    }
    }
    };
    }
    //tslint:禁用下一行:无需var
    const consumer:SourceMapConsumer=新的SourceMapConsumer(require('main.js.map'));//高CPU使用率!
    常量缓存:{[key:string]:string}={};
    函数getSourceMapStackTrace(错误:错误|字符串):字符串{
    const originalStackTrace:string=error instanceof error?error.stack as string:error;
    if(缓存[originalStackTrace]){
    返回缓存[originalStackTrace];
    }
    常量re=/^\s+at\s+(.+?\s+)\(([0-z.\u\-\\/]+):(\ d+):(\d+)?$/gm;
    let match:RegExpExecArray | null;
    let outputStackTrace:string=error.toString();
    //tslint:禁用下一行:无条件赋值
    while((match=re.exec(originalStackTrace))!==null){
    const nameFromOriginalStackTrace:string=match[1];
    const IsStackTraceLineControl ByMe:boolean=匹配[2]=='main';
    const lineFromOriginalStackTrace:number=parseInt(匹配[3],10);
    const columnFrominalsTackTrace:number=parseInt(匹配[4],10);
    如果(!IsStackTraceLineControl ByMe){
    打破
    }
    常量{name,source,line,column}:MappedPosition=consumer.originalPositionFor({
    column:ColumnFromInitialStackTrace,
    line:lineFromOriginalStackTrace,
    });
    如果(!行){
    打破
    }
    const finalName=(name)?name:(nameFromOriginalStackTrace)?nameFromOriginalStackTrace:“”;
    outputStackTrace+=StripWebPackageFromStackTrace(
    `\n位于${finalName}(${source}:${line}:${column})`,
    );
    }
    cache[originalStackTrace]=outputStackTrace;
    返回outputStackTrace;
    }
    函数printOriginalError(错误:error){
    const message=`源映射在模拟模式下不工作。`;
    log(`${message}\n${escape(error.stack)}`);
    }
    函数printStackTrace(错误:error){
    const errorMessage=escape(getSourceMapStackTrace(错误));
    log(`${errorMessage}`);
    通知(错误消息);
    }
    函数stripWebpackFromStackTrace(文本:string):string{
    返回文本。替换('webpack://','';
    }
    


    另外,感谢,因为它帮助我了解了Screeps用例中
    源代码映射
    库的用法。如果我不想编写和理解我所有的尖叫代码并坚持使用Webpack,我可能不需要在这个问题上花费太多

    嘿,干得好!你知道为什么源地图不能在模拟模式下工作吗?我仍在进行原型设计,还没有准备好在尖叫声上花钱。
    import { escape } from 'lodash';
    import { MappedPosition, SourceMapConsumer } from 'source-map'; // leave it at version ^0.6.1. ^0.7 is async only.
    
    export default function errorMapper(tick: () => void): () => void {
        return () => {
            try {
                tick();
            } catch (error) {
                if (error instanceof Error) {
                    const isSimulation: boolean = ('sim' in Game.rooms);
                    if (isSimulation) {
                        printOriginalError(error);
                    } else {
                        printStackTrace(error);
                    }
                } else {
                    throw error;
                }
            }
        };
    }
    
    // tslint:disable-next-line: no-var-requires
    const consumer: SourceMapConsumer = new SourceMapConsumer(require('main.js.map')); // High CPU usage!
    const cache: { [key: string]: string } = {};
    
    function getSourceMapStackTrace(error: Error | string): string {
        const originalStackTrace: string = error instanceof Error ? error.stack as string : error;
        if (cache[originalStackTrace]) {
            return cache[originalStackTrace];
        }
    
        const re = /^\s+at\s+(.+?\s+)?\(?([0-z._\-\\\/]+):(\d+):(\d+)\)?$/gm;
        let match: RegExpExecArray | null;
        let outputStackTrace: string = error.toString();
    
        // tslint:disable-next-line:no-conditional-assignment
        while ((match = re.exec(originalStackTrace)) !== null) {
            const nameFromOriginalStackTrace: string = match[1];
            const isStackTraceLineControlledByMe: boolean = match[2] === 'main';
            const lineFromOriginalStackTrace: number = parseInt(match[3], 10);
            const columnFromOriginalStackTrace: number = parseInt(match[4], 10);
    
            if (!isStackTraceLineControlledByMe) {
                break;
            }
    
            const { name, source, line, column }: MappedPosition = consumer.originalPositionFor({
                column: columnFromOriginalStackTrace,
                line: lineFromOriginalStackTrace,
            });
    
            if (!line) {
                break;
            }
    
            const finalName = (name) ? name : (nameFromOriginalStackTrace) ? nameFromOriginalStackTrace : '';
    
            outputStackTrace += stripWebpackFromStackTrace(
                `\n    at ${finalName}(${source}:${line}:${column})`,
            );
        }
    
        cache[originalStackTrace] = outputStackTrace;
        return outputStackTrace;
    }
    
    function printOriginalError(error: Error) {
        const message = `Source maps don't work in the Simulation mode.`;
        console.log(`<span style="color: tomato">${message}\n${escape(error.stack)}</span>`);
    }
    
    function printStackTrace(error: Error) {
        const errorMessage = escape(getSourceMapStackTrace(error));
        console.log(`<span style="color: tomato">${errorMessage}</span>`);
        Game.notify(errorMessage);
    }
    
    function stripWebpackFromStackTrace(text: string): string {
        return text.replace('webpack:///', '');
    }