LoginSignup
2
1

More than 1 year has passed since last update.

Salesforce B2C Commerce で利用できる sgmf-scripts について

Last updated at Posted at 2022-09-09

※ これから記載する事項は、私が所属する会社とは一切関係のない事柄です。

今回の記事ではカートリッジの開発やCI/CDに利用できるツールである、sgmf-scriptsを紹介いたします。
Info Centerで「sgmf-scripts」で検索しても使い方は結構出て来ますので、参考にしてみてください。

sgmf-scripts って何ができるの?

  • カートリッジの作成
  • カートリッジのアップロード
  • ユニットテスト
  • インテグレーションテスト
  • JS、SCSSなどの静的ファイルのコンパイル
  • JS、CSS ファイルのリントチェック
  • リアルタイムでファイルをビルド&アップロード

sgmf-scripts を使ってみる

node-sassのバージョンの関係で、Node 14じゃないと動かなさそうです。
今回は v14.17.6 を利用しました。

〜〜まず準備(カートリッジの作成)〜〜

  1. 任意の場所に作業用フォルダを作成する
  2. npm install sgmf-scripts --save-devでインストール
  3. npx sgmf-scripts --createCartridge [任意のカートリッジ名] で環境を作成
  4. dw.json 内に hostname, username, password を入力

SFRAの依存関係を利用してビルドする場合

  • cartridges フォルダ内に app_storefront_base カートリッジを設置。
  • package.json内に下記の内容を追加してbase というエイリアスでモジュールを読み込めるようにする。
package.json
{
====OMIT===
    "paths": {
        "base": "./cartridges/app_storefront_base"
    },
====OMIT===
}
  • npm install bootstrap --save-dev でインストール
  • 下記の内容をルートにある webpack.config.js と置き換える
webpack.config.js
var path = require('path');
var webpack = require('sgmf-scripts').webpack;
var ExtractTextPlugin = require('sgmf-scripts')['extract-text-webpack-plugin'];
var sgmfScripts = require('sgmf-scripts');

var bootstrapPackages = {
  Alert: 'exports-loader?Alert!bootstrap/js/src/alert',
  // Button: 'exports-loader?Button!bootstrap/js/src/button',
  Carousel: 'exports-loader?Carousel!bootstrap/js/src/carousel',
  Collapse: 'exports-loader?Collapse!bootstrap/js/src/collapse',
  // Dropdown: 'exports-loader?Dropdown!bootstrap/js/src/dropdown',
  Modal: 'exports-loader?Modal!bootstrap/js/src/modal',
  // Popover: 'exports-loader?Popover!bootstrap/js/src/popover',
  Scrollspy: 'exports-loader?Scrollspy!bootstrap/js/src/scrollspy',
  Tab: 'exports-loader?Tab!bootstrap/js/src/tab',
  // Tooltip: 'exports-loader?Tooltip!bootstrap/js/src/tooltip',
  Util: 'exports-loader?Util!bootstrap/js/src/util'
};

module.exports = [
  {
    mode: 'production',
    name: 'js',
    entry: sgmfScripts.createJsPath(),
    output: {
      path: path.resolve('./cartridges/app_custom_sfra/cartridge/static'),
      filename: '[name].js'
    },
    module: {
      rules: [
        {
          test: /bootstrap(.)*\.js$/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/env'],
              plugins: ['@babel/plugin-proposal-object-rest-spread'],
              cacheDirectory: true
            }
          }
        }
      ]
    },
    plugins: [new webpack.ProvidePlugin(bootstrapPackages)]
  },
  {
    mode: 'none',
    name: 'scss',
    entry: sgmfScripts.createScssPath(),
    output: {
      path: path.resolve('./cartridges/app_custom_sfra/cartridge/static'),
      filename: '[name].css'
    },
    module: {
      rules: [
        {
          test: /\.scss$/,
          use: ExtractTextPlugin.extract({
            use: [
              {
                loader: 'css-loader',
                options: {
                  url: false,
                  minimize: true
                }
              },
              {
                loader: 'postcss-loader',
                options: {
                  // eslint-disable-next-line global-require
                  plugins: [require('autoprefixer')()]
                }
              },
              {
                loader: 'sass-loader',
                options: {
                  includePaths: [
                    path.resolve('node_modules'),
                    path.resolve('node_modules/flag-icon-css/sass')
                  ]
                }
              }
            ]
          })
        }
      ]
    },
    plugins: [new ExtractTextPlugin({ filename: '[name].css' })]
  }
];

〜〜カートリッジのアップロード〜〜

## 特定のカートリッジのアップロード
npm run uploadCartridge [カートリッジ名]
## 例: npm run uploadCartridge app_custom_sfra

## 特定のファイルのアップロード
npx sgmf-scripts --upload [ファイルパス(ワイルドカードも使える)]
## 例:npx sgmf-scripts --upload cartridges/app_custom_sfra/cartridge/controllers/*

npm run upload [ファイルパス]を利用する場合は、package.json 内の "upload": "sgmf-scripts --upload --", をから「--」を削除して "upload": "sgmf-scripts --upload", に変更してください 。

〜〜ユニットテスト〜〜

  • 任意のフォルダを作成(例: test/unitフォルダをフォルダのルートに作成)し、下記コマンドを実行。
## テスト実行
npx sgmf-scripts --test [ファイルパス]
## 例: sgmf-scripts --test test/unit/**/*.js

## テストカバレッジの取得(coverageフォルダに結果出力)
npx sgmf-scripts --cover [テストフォルダ]
## 例: sgmf-scripts --cover 'test/unit'

[サンプルコード]テストされるコード

cartridges/app_custom_sfra/cartridge/scripts/test.js
'use strict';

var server = require('server');

function test(a) {
  return server.test(a);
}

module.exports = {
  test: test
};

[サンプルコード]テストするコード

test/unit/app_custom_sfra/scripts/test.js
'use strict';

var assert = require('chai').assert;
var proxyquire = require('proxyquire').noCallThru().noPreserveCache();

describe('Test a + 1', function () {
  var test = proxyquire(
    '../../../../cartridges/app_custom_sfra/cartridge/scripts/test',
    {
      server: {
        test: function (a) {
          return a + 1;
        }
      }
    }
  );

  it("should append an object's key/value pairs to a provided url", function () {
    var result = test.test(1);
    assert.equal(result, 2);
  });
});

〜〜インテグレーションテスト〜〜

  • 任意のフォルダを作成(例:test/integrationフォルダをフォルダのルートに作成)し、下記コマンドを実行。
## インテグレーションテスト
npx sgmf-scripts --integration [テストファイルパス] --baseUrl [テストする環境のベースURL]
## 例: npx sgmf-scripts --integration test/integration/**/*.js --baseUrl https://zzjs-021.sandbox.us02.dx.commercecloud.salesforce.com/on/demandware.store/Sites-RefArch-Site/en_US

[サンプルコード]テストされるコントローラー

cartridges/app_custom_sfra/cartridge/controllers/Test.js
'use strict';

var server = require('server');

server.get('Json', function (req, res, next) {
  res.json({ test: 'test' });
  return next();
});

module.exports = server.exports();

[サンプルコード]テストするコード

下記のサンプルコードを利用する前は下記のコマンドで request-promise をインストールしてください。

npm install request-promise --save-dev
test/integration/sample/test.js
var assert = require('chai').assert;
var request = require('request-promise');
var optionator = require('optionator')(require('sgmf-scripts/lib/utils/options'));
var options = optionator.parse(process.argv);

describe('Test.js', function () {
  this.timeout(5000);

  it('Test test prop', function (done) {
    var myRequest = {
      url: '',
      method: 'GET',
      rejectUnauthorized: false,
      headers: {
        'X-Requested-With': 'XMLHttpRequest'
      }
    };
    myRequest.url = options.baseUrl + '/Test-Json';
    request(myRequest, function (error, response) {
      var bodyAsJson = JSON.parse(response.body);
      assert.equal(response.statusCode, 200, 'Expected statusCode to be 200.');
      assert.equal(bodyAsJson.test, 'test', 'Expected test prop equal "test".');
      done();
    });
  });
});

〜〜JS、 SCSSなどの静的ファイルのコンパイル〜〜

npx sgmf-scripts --compile js
npx sgmf-scripts --compile css

[サンプルコード]JS

cartridges/app_custom_sfra/cartridge/client/default/js/test.js
'use strict';

// var processInclude = require('base/util');
$(document).ready(function () {
  // processInclude(require('./storeLocator/storeLocator'));
});

[サンプルコード]SCSS

cartridges/app_custom_sfra/cartridge/client/default/scss/test.scss
@import "base/homePage";

.test {
  color: red;
}

〜〜JS、CSS ファイルのリントチェック〜〜

下記のコマンドでリントをチェックする。

npx sgmf-scripts --lint css
npx sgmf-scripts --lint js

※リントするにあたって何点か注意点があります。

1. テストコードの内のmocha のメソッドで "describe" in not defined のようなエラーが出る。静的ファイル内で "$" in not defined のようなエラーが出る。

.eslintrc.json 内に下記の行を追加してください。

.eslintrc.json
"env": {
    "mocha": true,
    "jquery" : true
 }

2. app_storefront_base カートリッジ内などの必要ないコードまでリントされてしまう。

下記のファイルをフォルダのルートに設置して、特定のcssとjsを対象から外す

特定のJSを対象から外すサンプルコード

.eslintignore
cartridges/app_storefront_base/**/*
cartridges/**/cartridge/static/default/js/**/*
coverage/
doc/
bin/

特定のSCSSを対象から外すサンプルコード

.stylelintignore
cartridges/app_storefront_base/**/*
cartridges/**/cartridge/static/default/css/**/*

〜〜リアルタイムでファイルをビルド&アップロード〜〜

下記コマンドを実行すると、実行中に編集したファイルがリアルダイムにアップロードされる。(静的ファイルはビルドされる)

## リアルタイムでファイルをビルド&アップロード
npx sgmf-scripts --watch
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1