@bigcommerce/stencil-cli 9.0.3 → 9.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,7 +8,7 @@ The BigCommerce server emulator for local theme development.
8
8
  ## Install
9
9
 
10
10
  Note: Stencil requires the Node.js runtime environment,
11
- versions 20.x, 22.x are supported.
11
+ version 24.x or later is required.
12
12
 
13
13
  Run `npm install -g @bigcommerce/stencil-cli`.
14
14
 
@@ -97,6 +97,28 @@ If you need any help or experience any bugs, please create a GitHub issue in thi
97
97
  If you would like to improve this project check out the [Contributing Guide](./CONTRIBUTING.md). Also, you can find
98
98
  the implementation details there.
99
99
 
100
+ ## Versioning and releases
101
+
102
+ Stencil CLI uses [Semantic Release](https://semantic-release.gitbook.io/semantic-release/). The commit message used when a pull
103
+ request is merged determines the next version.
104
+
105
+ Use [Conventional Commits](https://www.conventionalcommits.org/) for pull request titles and merge commit
106
+ messages:
107
+
108
+ - `fix:` creates a patch release.
109
+ - `feat:` creates a minor release.
110
+ - A breaking change creates a major release. Add `BREAKING CHANGE:` as a commit footer, or append `!` to the
111
+ commit type (for example, `feat!:`).
112
+
113
+ For example:
114
+
115
+ ```text
116
+ feat!: require Node.js 24
117
+ ```
118
+
119
+ After the pull request is merged, Semantic Release creates the GitHub release and publishes the new version to npm.
120
+ See the [Contributing Guide](./CONTRIBUTING.md) for more information.
121
+
100
122
  ## Running in docker
101
123
 
102
124
  There is possibility to run stencil-cli in docker.
@@ -2,10 +2,9 @@ import { once } from 'lodash-es';
2
2
  import { fork } from 'child_process';
3
3
  import path from 'path';
4
4
  import fsModule from 'fs';
5
- import { createRequire } from 'node:module';
5
+ import { pathToFileURL } from 'node:url';
6
6
  import { THEME_PATH } from '../constants.js';
7
7
 
8
- const require = createRequire(import.meta.url);
9
8
  const isJest = typeof process !== 'undefined' && 'JEST_WORKER_ID' in process.env;
10
9
 
11
10
  const cornerstoneConfigLink = isJest
@@ -16,8 +15,10 @@ class BuildConfigManager {
16
15
  constructor({ workDir = THEME_PATH, fs = fsModule, timeout = 20000 } = {}) {
17
16
  this.oldConfigFileName = 'stencil.conf.js';
18
17
  this.configFileName = 'stencil.conf.cjs';
18
+ this.esmConfigFileName = 'stencil.conf.mjs';
19
19
  this._workDir = workDir;
20
20
  this._buildConfigPath = path.join(workDir, this.configFileName);
21
+ this._esmBuildConfigPath = path.join(workDir, this.esmConfigFileName);
21
22
  this._oldBuildConfigPath = path.join(workDir, this.oldConfigFileName);
22
23
  this._fs = fs;
23
24
  this._onReadyCallbacks = [];
@@ -27,15 +28,19 @@ class BuildConfigManager {
27
28
  }
28
29
 
29
30
  async initConfig() {
30
- const config = await this._getConfig(this._buildConfigPath, this._oldBuildConfigPath);
31
+ const config = await this._getConfig(
32
+ this._resolveBuildConfigPath(),
33
+ this._oldBuildConfigPath,
34
+ );
31
35
  this.development = config.development || this._devWorker;
32
36
  this.production = config.production || this._prodWorker;
33
37
  this.watchOptions = config.watchOptions;
34
38
  }
35
39
 
36
40
  initWorker() {
37
- if (this._fs.existsSync(this._buildConfigPath)) {
38
- this._worker = fork(this._buildConfigPath, [], { cwd: this._workDir });
41
+ const buildConfigPath = this._resolveBuildConfigPath();
42
+ if (this._fs.existsSync(buildConfigPath)) {
43
+ this._worker = fork(buildConfigPath, [], { cwd: this._workDir });
39
44
  this._worker.on('message', (message) => {
40
45
  if (message === 'ready') {
41
46
  this._workerIsReady = true;
@@ -50,23 +55,38 @@ class BuildConfigManager {
50
55
  this._worker.kill(signal);
51
56
  }
52
57
 
58
+ // Prefer an ESM stencil.conf.mjs when the theme provides one; otherwise
59
+ // use the CommonJS stencil.conf.cjs (which legacy stencil.conf.js files
60
+ // get renamed to)
61
+ _resolveBuildConfigPath() {
62
+ if (this._fs.existsSync(this._esmBuildConfigPath)) {
63
+ return this._esmBuildConfigPath;
64
+ }
65
+ return this._buildConfigPath;
66
+ }
67
+
53
68
  async _getConfig(configPath, oldConfigPath) {
54
69
  if (this._fs.existsSync(configPath)) {
55
- // eslint-disable-next-line import/no-dynamic-require
56
- return require(configPath);
70
+ return this._importConfig(configPath);
57
71
  }
58
72
  if (this._fs.existsSync(oldConfigPath)) {
59
73
  this._moveOldConfig(configPath, oldConfigPath);
60
- // eslint-disable-next-line import/no-dynamic-require
61
- return require(configPath);
74
+ return this._importConfig(configPath);
62
75
  }
63
76
 
64
77
  // Fallback to cornerstone default stencil.conf.cjs
65
78
  const content = await this.downloadFileFromGitHub(cornerstoneConfigLink);
66
79
  this._fs.writeFileSync(configPath, content);
67
80
 
68
- // eslint-disable-next-line import/no-dynamic-require
69
- return require(configPath);
81
+ return this._importConfig(configPath);
82
+ }
83
+
84
+ // Dynamic import() loads both ESM and CommonJS configs. CommonJS exposes
85
+ // module.exports as the default export; ESM configs use named exports
86
+ async _importConfig(configPath) {
87
+ // eslint-disable-next-line node/no-unsupported-features/es-syntax
88
+ const configModule = await import(pathToFileURL(configPath).href);
89
+ return configModule.default ?? configModule;
70
90
  }
71
91
 
72
92
  async downloadFileFromGitHub(rawUrl) {
@@ -34,6 +34,7 @@ const PATHS_TO_ZIP = [
34
34
  { pattern: '.scss-lint.yml' },
35
35
  { pattern: 'stencil.conf.cjs' },
36
36
  { pattern: 'stencil.conf.js' },
37
+ { pattern: 'stencil.conf.mjs' },
37
38
  { pattern: 'templates/**/*' },
38
39
  { pattern: 'webpack.*.js' },
39
40
  ];
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@bigcommerce/stencil-cli",
3
- "version": "9.0.3",
3
+ "version": "9.2.0",
4
4
  "type": "module",
5
5
  "description": "CLI tool to run BigCommerce Stores locally for theme development.",
6
6
  "main": "index.js",
7
7
  "engines": {
8
- "node": ">=20",
8
+ "node": ">=24",
9
9
  "npm": ">=8.0.0"
10
10
  },
11
11
  "scripts": {