javascriptnode.jstypescriptyeoman-generator

how to read ts file and update code dynamically using fs?


i am scaffolding new project using yeoman generator it is creating all the directories and running dependencies , now once files are generated i want to update js class same as appName, first i am trying to read the ts file which i failed to do it throws error TypeError: Cannot read property 'toString' of undefined then i would update the file with appName if there is any better approach to achieve this task i will apprecaite the help.

index.js

 updateTsFile () {
    const npmdir = `${process.cwd()}/${this.props.appName}`;
    const dirPath = `${npmdir}/${"./api.ts"}`;
    console.log("path", dirPath);
    let response;
    _fs.readFile(dirPath, (_err, res) => {
      if (_err) {
        console.error(_err);
      }

      let file = res.toString("utf-8");
      console.log(file);
      response = file;
      let lines = file.split("\n");
      for (let i = 0; i < lines.length; i++) {
        console.log(lines[i]);
      }
    });
    return response;
  }

api.ts

export class CAPIClass extends Wrapper {
    public after = after;
    constructor() {
        super({
            configFileName: "package-name-v1.json"
        });
    }
}

expected output

export class CMyAppNameClass extends Wrapper {
    public after = after;
    constructor() {
        super({
            configFileName: "package-name-v1.json"
        });
    }
}

Solution

  • In case of an error you're just logging the error but continuing with the logic. So it seems like you're running into an error resulting in res being undefined. Since fs exposes a promise-based api nowadays, I would rewrite this as follows instead of using callbacks (also note that you were using utf-8 for the encoding but it should be utf8):

    async updateTsFile() {
        const npmdir = `${process.cwd()}/${this.props.appName}`;
        const dirPath = `${npmdir}/${"./api.ts"}`;
        console.log("path", dirPath);
    
        try {
            const fileData = await _fs.promises.readFile(dirPath);
            const fileAsStr = fileData.toString("utf8");
    
            // replace class-name
            fileAsStr = fileAsStr.replace(/CAPIClass/g, "CMyAppNameClass");
            // (over)write file: setting 'utf8' is not actually needed as it's the default
            await _fs.promises.writeFile(dirPath, fileAsStr, 'utf8');
        } catch (err) {
            console.log(err);
            // handle error here
        }
    
    }