1

I am trying to use webpack to bundle a few libraries into my typescript suitelet.

Netsuite expects suitescripts to follow amd modules pattern. If I use tsc tocompile my suitelet, I get correct syntax that looks this fragment:

/**
 *
 * @NApiVersion 2.x
 * @NScriptType Suitelet
 */
define(["require", "exports", "N", "N/file"], function (require, exports, N_1, file_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.onRequest = void 0;
    var onRequest = function (context) {
        //my actual code here
    };
    exports.onRequest = onRequest;
});

The poblem is that the dependencies from node_modules are not bundled. So I have tried to use webpack for this, and webpack output differs:

/**
 *
 * @NApiVersion 2.x
 * @NScriptType Suitelet
 */
define(["N", "N/file"], (__WEBPACK_EXTERNAL_MODULE__N, __WEBPACK_EXTERNAL_MODULE__Nfile) => {
    return (() => {
        //... some webpack internals goes here
        var __webpack_exports__ = {};
        // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
        (() => {
            __webpack_require__.r(__webpack_exports__);
            /* harmony export */
            __webpack_require__.d(__webpack_exports__, {
                /* harmony export */   "onRequest": () => (/* binding */ onRequest)
                // harmony imports goes here, cut for readability
            });

            var onRequest = function onRequest(context) {
                //my actual code here
            };
        })();
        return __webpack_exports__;
    })();
});

Netsuite does not accept the version webpack produces. I assume that the problem is that webpack returns the exported module, but Netsuite expect's it to be passed as the 2nd parameter to the module factory function and modified by it. tsc does that. It modifies the export parameter adding the onRequest function to the export object. Webpack just return new object.

How should I configure webpack to follow the define(["require","exports","other-dependencies"], factory_function); convention?

Here are the fragments of my webpack.config.js:

module.exports = {
    entry: glob.sync('.src/**.ts').reduce((obj, el) => {
        obj[path.parse(el).name] = el;
        return obj;
    }, {}),
    output: {
        filename: '[name].js',
        libraryTarget: 'amd',
        path: path.resolve(__dirname, 'dist'),
        globalObject: 'this',
    },
    resolve: {
        extensions: ['.ts', '.js'],
        modules: [
            path.resolve(__dirname, 'node_modules'),
            'node_modules'
        ]
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: 'babel-loader',
            },
        ],
    },
    optimization: {
        // Do not remove the SuiteScript JSDoc when minifying
        minimize: false,
        minimizer: [
            new TerserPlugin({
                terserOptions: {
                    output: {
                        comments: /@NApiVersion/i,
                    },
                },
            }),
        ],
    },
    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.length ? comments[0] : '';
            },
            raw: true,
        }),
    ],
    externals: [/^N\//, /^N$/],
    externalsType: 'umd'
};
SWilk
  • 3,261
  • 8
  • 30
  • 51

0 Answers0