Hi, Does anyone have experience importing 3rd par...
# suitescript
s
Hi, Does anyone have experience importing 3rd party library's (that use ts, tsx, etc..) in NetSuite? For example I'm trying to implement PDFme into my project but cant get it to work. I'm not very familiar with webpack and babel buy tried using it the past few days but I'm keeping on getting errors. I'm aware of these two libraries (typings-suitescript-2.0 and netsuite-webpack) and tried to copy the configuration but couldn't get it to work. If anyone can help me i would greatly appreciate it.
j
We have successfully managed to get Typescript and Webpack working in a way that allows us to generate scripts that can be used in Netsuite.
We are using the headintheclouds typings too which should help. Here is our tsconfig.json
Copy code
{
  "compilerOptions": {
    "outDir": "dist",
    "module": "AMD",
    "target": "es5",
    "moduleResolution":"node",
    "sourceMap": false,
    "newLine": "LF",
    "experimentalDecorators": true,
    "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
    // "noImplicitUseStrict": true,
    "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. */
    "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
    "baseUrl": ".",
    "lib": ["es5", "es2015.promise", "dom"],
    "paths": {
      "N": ["node_modules/@hitc/netsuite-types/N"],
      "N/*": ["node_modules/@hitc/netsuite-types/N/*"]
    }
  },
  "exclude": ["node_modules", "jest.config.ts", "**/__tests__/**"]
}
this should all you to compile your typescript files.
And here is the webpack.config.js
Copy code
const path = require("path");
const webpack = require("webpack");
const fs = require("fs");

/**
 * Folder to place packed files in
 */
const outFolder = path.resolve(
  __dirname,
  "deploy/FileCabinet/SuiteApps/com.netsuite.myscripts/SuiteScripts/"
);

/**
 * Add All Entry point scripts here, the key will be used for output filename.
 */
const entries = {
  my_suitelet: "./src/suitelets/my_suitelet/index.ts",
  my_userevent: "./src/user-events/my_userevent/index.ts",
};

/**
 * Add Aliases below and in tsconfig.json paths. Ensure to use absolute path or path.resolve(__dirname,<RELATIVE PATH>)
 */
const aliases = {
  //   helpers: path.resolve(__dirname, "src/TypeScript/helpers"),
  //   definitions: path.resolve(__dirname, "src/TypeScript/definitions"),
  //   services: path.resolve(__dirname, "src/TypeScript/services"),
};

/**
 * This reads the deploy.xml and gets all the .js files that we want to deploy
 * and then filters the entries-list above to only build the relevant .js-files
 */
const lineArray = fs.readFileSync("./deploy/deploy.xml").toString().split("\n");
const jsFilesToDeploy = lineArray
  .filter((lineText) => lineText.includes(".js"))
  .map((lineText) => /\/SuiteScripts\/(.*)[.]js/.exec(lineText)[1]);
console.log("JS-files in the deploy.xml", jsFilesToDeploy);
const entriesToDeploy = Object.entries(entries).reduce(
  (filteredList, entry) => {
    if (jsFilesToDeploy.includes(entry[0])) {
      filteredList[entry[0]] = entry[1];
    }
    return filteredList;
  },
  {}
);
console.log("Matching entries in Webpack.config.js", entriesToDeploy);

/**
 * Main Webpack Configuration, change with care
 */
module.exports = {
  entry: entries,
  mode: "production",
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: "ts-loader",
        exclude: "/node_modules/",
      },
    ],
  },
  optimization: {
    minimize: false,
    moduleIds: "named",
  },
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
    alias: aliases,
  },
  plugins: [
    // Copy the SuiteScript JSDoc to the top of the script
    new webpack.BannerPlugin({
      banner: (data) => {
        const filename = data.chunk.entryModule.resource;
        const contents = fs.readFileSync(filename, "UTF-8");
        const comments = contents.match(/\/\*[\s\S]*?\*\//);
        return comments && comments.length ? comments[0] : "";
      },
      raw: true,
    }),
  ],
  output: {
    path: outFolder,
    filename: "[name].js",
    libraryTarget: "amd",
  },
  externals: [/^N\//],
};
the trick here is the
Copy code
const entries = {
  my_suitelet: "./src/suitelets/my_suitelet/index.ts",
  my_userevent: "./src/user-events/my_userevent/index.ts",
};
at the top of the file. This will create a single output file for each entry point entered here and will bundle any 3rd party modules used. Also note
Copy code
const outFolder = path.resolve(
  __dirname,
  "deploy/FileCabinet/SuiteApps/com.netsuite.myscripts/SuiteScripts/"
);
at the top of the file which sets the output directory. We are using the the Netsuite CLI to deploy hence the reference to the FileCabinet
And finally here is the deploy.xml file referenced in the webpack.config
Copy code
<deploy>
    <files>
        <path>~/FileCabinet/SuiteApps/com.netsuite.myscripts/SuiteScripts/*</path>
    </files>
    <objects>
        <path>~/Objects/*</path>
    </objects>
</deploy>
Hope this helps you get setup
w
Nice webpack.config.js you got there, looks very familiar 😄
But since you are not using the variable
jsFilesToDeploy
, the point of referencing deploy.xml in webpack.config.js is moot.
j
Thanks Watz I was going to add a reference to your repo but got distracted with a work issue (work always gets in the way). Your repo was an excellent reference to getting this working for us. So a big thank you to you 😄
w
No worries, it's not really "mine" anyways. It's probably based on Michoel's. Just recognized the part about reading the deploy-file that was put together by ChatGPT 🤖
🙌 1