Create a Custom Module

This topic applies to

Applies to

SuiteCommerce Advanced

 

Note

The module source files for SuiteCommerce Advanced 2019.1 and earlier are JavaScript files with .js filename extensions. The module source files for SuiteCommerce Advanced 2019.2 and later are TypeScript files with .ts filename extensions. For more information about TypeScript, see TypeScript.


SuiteCommerce Advanced (SCA) is designed so that you can extend it by creating new modules to add functionality specific to your web store. When creating a new module, be aware of the following requirements:

  • The top level directory of your module should have a directory of the format: module_name@x.y.z where module_name is the name of the module and x.y.z is the version number. See Organize Source Code for Custom Modules

  • The directory containing your custom module must be in the correct directory. Examples in this document name this directory extensions; however, you can name this directory any intuitive name as required.

    • For 2019.2 and later, SCA source code modules are stored in three sub-directories: Advanced, Backend, and Commons. Create another sub-directory at the same directory level to store all custom module code. Example: SC_19.2_Live/extensions.

    • For 2019.1 and earlier, the directory containing your custom module must be in the Modules directory. Modules shipped with SCA are stored in two sub-directories, suitecommerce and third_parties. Create a third sub-directory to store all custom module code. Example: Modules/extensions.

  • Your new modules directory must have an ns.package.json file to define all of the module dependencies required by the developer tools. For more information, see Core SuiteCommerce Advanced Developer Tools for more information.

  • The module name must be unique. You cannot have duplicate module names, even when they reside in different folders.

  • You must update the distro.json file to ensure that your custom module is loaded into the application.

To add a custom module:

  1. Create a custom module directory within your custom directory with the format of ModuleName@version.

    Examples:

    • If implementing 2019.2 and later, create this directory in the extensions directory. For example: SC_19.2_Live/extensions/MyCustomModule@1.0.0.

    • If implementing 2019.1 and earlier, create this directory in the Modules/extensions directory. For example: Modules/extensions/MyCustomModule@1.0.0.

    Important

    You cannot use existing module names, even when those modules reside in different folders.


  2. Create the subdirectories within the module.

    The exact subdirectory structure depends on the requirements of your module and your implementation of SCA. NetSuite recommends that you use the same directory structure as existing application modules. Typically, you will need JavaScript, Sass, SuiteScript, and Templates subdirectories.

  3. Create the necessary files for your module.

    This is where all of your modules logic is contained. These files are either JavaScript (.js) or TypeScript (.ts) depending on your implementation of SCA. At a minimum, you will need something like the following:

    Note

    This procedure does not include examples of backend models or services files which are often necessary for backend integration with NetSuite.


    • Entry point – this file acts as an entry point to the module and must return an object containing the mountToApp property that receives the application as a parameter.

      JavaScript example:

      //MyNewModule.js define('MyNewModule' , [ 'MyNewModule.Router' ] , function ( Router ) { 'use strict'; return { mountToApp: function (application) { // Initializes the router return new Router(application); } }; });

      TypeScript example:

      ///<amd-module name = "MyNewModule"/> import Router = require('./Router'); export function mountToApp(application) { new Router(application); }
    • Router – if you are on SuiteCommerce 2019.1 or later, use extensions or a page type component. If you are on SuiteCommerce 2018.2 or earlier, this JavaScript file extends the Backbone router to map URL patterns to the views defined within the module.

      //MyNewModule.Router.js define('MyNewModule.Router' , [ 'MyNewModule.View' , 'Backbone' ] , function ( MyNewModuleView , Backbone ) { 'use strict'; //@class Address.Router @extend Backbone.Router return Backbone.Router.extend({ routes: { 'my-new-module': 'MyNewModuleRouter' } , initialize: function (application) { this.application = application; } // list myNewRouter output , MyNewModuleRouter: function () { var view = new MyNewModuleView({ application: this.application }) view.showContent(); } }); });
    • View – this view is called from the router. Often, a view contains a getContext function that describes all of the variables that are passed from the view to the template.

      JavaScript example:

      //MyNewModule.View.js define( 'MyNewModule.View' , [ 'my_new_module.tpl' , 'Backbone' , 'jQuery' ] , function ( MyNewModuleTemplate , Backbone , jQuery ) { 'use strict'; //@class Address.List.View List profile's addresses @extend Backbone.View return Backbone.View.extend({ template: MyNewModuleTemplate , events: { 'click [data-action="test"]': 'testAction' } , testAction: function () { alert("This is a test action") } , getContext: function () { return { //@property {String} myNewModuleContextVar myNewModuleContextVar: 'myVariable' }; } }); });

      TypeScript example:

      /// <amd-module name="MyNewModule.View"/> import my_new_module.tpl = require('.//../my_new_module.tpl'); import Backbone = require('../../../Commons/Utilities/JavaScript/backbone.custom'); import jQuery = require('../../../Commons/Utilities/JavaScript/jQuery'); //@class Address.List.View List profile's addresses @extend Backbone.View let BackboneViewExtend: any = Backbone.View.extend({ template: MyNewModuleTemplate, events: { 'click [data-action="test"]': 'testAction' }, testAction: function () { alert("This is a test action") }, getContext: function () { return { //@property {String} myNewModuleContextVar myNewModuleContextVar: 'myVariable' }; } }); export = BackboneViewExtend;
    • Template – this file contains the markup used in combination with the views. Note that the SCA implementation leverages the Handlebars templating engine.

      <h2>This is my template file for my new module. It takes variables, {{myNewModuleContextVar}}, passed from the View.</h2>

      Important

      Template file names must be unique. You cannot have duplicate template file names even when they belong to different modules.


  4. If your custom module contains any configurable properties, you must include a Configuration subdirectory and place your Configuration Modifications here. See Modify JSON Configuration Files for details.

    Note

    This step only applies to Vinson implementations of SCA and later.


  5. Create a new ns.package.json file within the new custom modules directory.

    • If implementing 2019.2 and later, consider this example: SC_19.2_Live/extensions/MyCustomModule@1.0.0/ns.package.json

    • If implementing 2019.1 and earlier, consider this example: Modules/extensions/MyCustomModule@1.0.0/ns.package.json

    This file must contain entries for all of the directories required by the module. Use the following example as a template:

    This file must contain entries for all of the directories required by the module. This file is either JavaScript (.js) or TypeScript (.ts) depending on your implementation of SCA.

    JavaScript example:

    { "gulp": { "javascript": [ "JavaScript/*.js" ] , "templates": [ "Templates/*.tpl" ] , "ssp-libraries": [ "SuiteScript/*.js" ] , "services.new": [ "SuiteScript/*.Service.ss" ] , "sass": [ "Sass/**/*.scss" ] } }

    TypeScript example:

    { "gulp": { "javascript": [ "JavaScript/*.js", "JavaScript/*.ts" ] , "templates": [ "Templates/*.tpl" ] , "ssp-libraries": [ "SuiteScript/*.js" ] , "services.new": [ "SuiteScript/*.Service.ss" ] , "sass": [ "Sass/**/*.scss" ] } }
  6. Update the distro.json file.

    • If implementing 2019.2 and later, this file is in the Advanced directory. For example: SC_19.2_Live/Advanced/distro.json.

    • If implementing 2019.1 and earlier, this file is in the root directory of the SCA source code.

    Update this file with the following two changes:

    • Add an entry for the new module in the modules object.

      • Example if implementing 2019.2 and later:

        { "name": "SuiteCommerce Advanced Live", "version": "2.0", "modules": { "Account", "../extensions/myNewModule": 1.0.0", "../Commons/Address", "../AjaxRequestKiller", "../Commons/ApplicationSkeleton", ... }
      • Example if implementing 2019.1 and earlier:

        { "name": "SuiteCommerce Advanced 1.0.0", "version": "1.0.0", "modules": { "suitecommerce/Account": "1.0.0", "extensions/myNewModule": "1.0.0", "suitecommerce/AjaxRequestsKiller": "1.0.0", "suitecommerce/ApplicationSkeleton": "1.0.0", ... }
    • Define any application dependencies in the javascript object.

      For example, if the module is required in the Shop Flow application, add the module to the SC.Shopping.Starter entrypoint.

      "javascript": [ { "entryPoint": "SC.Shopping.Starter", "exportFile": "shopping.js", "dependencies": [ "Backbone.View.Plugins", "jQuery.html", "ItemDetails", "myNewModule", ... "UrlHelper", "CMSadapter" ],
  7. View your changes.

    Important

    If you are on SuiteCommerce 2019.2 or later, all TypeScript (.ts) files are compiled to JavaScript (.js) files when executing the gulp local and gulp deploy commands.


    After creating your new module, you can test it by viewing your changes in the application. If you are running a local server, you can view your changes by reloading your website. See SCA on a Local Server for more information.

    If you are viewing your site in NetSuite, you can deploy your changes using the developer tools. See Deploy to NetSuite for more information.