balm-core 4.5.5 → 4.8.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.
Files changed (38) hide show
  1. package/README.md +3 -1
  2. package/index.d.ts +4 -2
  3. package/lib/balm.js +2 -2
  4. package/lib/bootstrap/check_config.js +1 -0
  5. package/lib/bundler/webpack/config/common.js +12 -1
  6. package/lib/bundler/webpack/config/dev.js +1 -3
  7. package/lib/bundler/webpack/config/env.js +67 -0
  8. package/lib/bundler/webpack/config/prod.js +1 -3
  9. package/lib/bundler/webpack/config/regex.js +1 -1
  10. package/lib/bundler/webpack/rules/asset.js +6 -1
  11. package/lib/bundler/webpack/rules/babel.js +6 -1
  12. package/lib/bundler/webpack/rules/index.js +3 -3
  13. package/lib/config/scripts.js +9 -4
  14. package/lib/config/styles.js +2 -0
  15. package/lib/hello.js +9 -3
  16. package/lib/plugins/sass.js +2 -2
  17. package/lib/tasks/foundation/balm_style.js +13 -1
  18. package/lib/utilities/compiling.js +2 -2
  19. package/lib/utilities/file.js +5 -3
  20. package/lib/utilities/loading.js +1 -1
  21. package/package.json +30 -28
  22. package/tslib/balm.js +1 -1
  23. package/tslib/bootstrap/check_config.js +1 -0
  24. package/tslib/bundler/webpack/config/common.js +3 -0
  25. package/tslib/bundler/webpack/config/dev.js +0 -3
  26. package/tslib/bundler/webpack/config/env.js +44 -0
  27. package/tslib/bundler/webpack/config/prod.js +0 -3
  28. package/tslib/bundler/webpack/config/regex.js +1 -1
  29. package/tslib/bundler/webpack/rules/asset.js +6 -1
  30. package/tslib/bundler/webpack/rules/babel.js +3 -1
  31. package/tslib/bundler/webpack/rules/index.js +3 -3
  32. package/tslib/config/scripts.js +6 -2
  33. package/tslib/config/styles.js +2 -0
  34. package/tslib/hello.js +7 -3
  35. package/tslib/tasks/foundation/balm_style.js +14 -1
  36. package/tslib/utilities/compiling.js +2 -2
  37. package/tslib/utilities/file.js +4 -2
  38. package/tslib/utilities/loading.js +1 -1
package/README.md CHANGED
@@ -13,6 +13,8 @@
13
13
  <p>An universal Front-End workflow for webapps</p>
14
14
  </div>
15
15
 
16
+ > [`balm-core@3`](https://github.com/balmjs/balm/tree/master)(v3) supports for `node@10.13.0+`, `postcss@7`, `webpack@4`
17
+
16
18
  ## Introduction
17
19
 
18
20
  BalmJS prescribes best practices and tools to help you stay productive.
@@ -91,7 +93,7 @@ yarn add -D balm@next
91
93
  OR
92
94
 
93
95
  ```sh
94
- npm install -g balm-core@next
96
+ npm install -g balm-core@next # Not supported for now (npm bug)
95
97
  npm install -D balm@next
96
98
  ```
97
99
 
package/index.d.ts CHANGED
@@ -29,6 +29,7 @@ interface BalmStyles {
29
29
  extname: string;
30
30
  minify: boolean;
31
31
  atImportPaths: string[];
32
+ entry: string | string[];
32
33
  options: object;
33
34
  sassOptions: object;
34
35
  lessOptions: object;
@@ -65,7 +66,6 @@ export type InputOptions = import('rollup').InputOptions;
65
66
  export type OutputOptions = import('rollup').OutputOptions;
66
67
  export type RollupOutput = import('rollup').RollupOutput;
67
68
  export type RollupBuild = import('rollup').RollupBuild;
68
- export type WatcherOptions = import('rollup').WatcherOptions;
69
69
 
70
70
  // Esbuild
71
71
  export type BuildOptions = import('esbuild').BuildOptions;
@@ -93,9 +93,12 @@ export interface BalmScripts {
93
93
  babelLoaderOptions: object;
94
94
  postcssLoaderOptions: Partial<PostcssLoaderOptions>;
95
95
  htmlLoaderOptions: object;
96
+ imageAssetType: string;
97
+ imageInlineSizeLimit: number;
96
98
  extensions: string[];
97
99
  alias: object;
98
100
  plugins: object[];
101
+ nodeEnv: object;
99
102
  injectHtml: boolean;
100
103
  htmlPluginOptions: object;
101
104
  extractCss: boolean;
@@ -111,7 +114,6 @@ export interface BalmScripts {
111
114
  // rollup
112
115
  inputOptions: Omit<InputOptions, 'acorn'>; // incompatible
113
116
  outputOptions: OutputOptions;
114
- watchOptions: WatcherOptions;
115
117
  // esbuild
116
118
  buildOptions: BuildOptions;
117
119
  useTransform: boolean;
package/lib/balm.js CHANGED
@@ -28,10 +28,10 @@ class Balm {
28
28
  value: void 0
29
29
  });
30
30
 
31
- _classPrivateFieldSet(this, _config, setConfig({}));
32
-
33
31
  BalmJS.loading = false;
34
32
  loading.succeed();
33
+
34
+ _classPrivateFieldSet(this, _config, setConfig({}));
35
35
  }
36
36
 
37
37
  get config() {
@@ -37,6 +37,7 @@ function checkConfig() {
37
37
  upgradeDeprecated('3.17.0', 'styles', 'darkSass');
38
38
  upgradeDeprecated('3.19.0', 'scripts', 'useCache'); // For v4
39
39
 
40
+ upgradeDeprecated('4.0.0', 'scripts', 'libraryTarget');
40
41
  upgradeDeprecated('4.5.0', 'scripts', 'excludeUrlResource');
41
42
  upgradeDeprecated('4.5.0', 'scripts', 'urlLoaderOptions');
42
43
  }
@@ -1,9 +1,20 @@
1
1
  import HtmlWebpackPlugin from 'html-webpack-plugin';
2
2
  import getLoaders from '../loaders.js';
3
3
  import { CHUNK } from '../../../config/constants.js';
4
+ import getClientEnvironment from './env.js';
4
5
 
5
6
  function getDefaultPlugins(webpack, scripts) {
6
- const plugins = [// Moment.js is an extremely popular library that bundles large locale files
7
+ // We will provide `BalmJS.file.publicUrlOrPath` to our app
8
+ // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
9
+ // Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
10
+ // Get environment variables to inject into our app.
11
+ const env = getClientEnvironment(BalmJS.file.publicUrlOrPath.slice(0, -1));
12
+ const plugins = [// Makes some environment variables available to the JS code, for example:
13
+ // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
14
+ // It is absolutely essential that NODE_ENV is set to production
15
+ // during a production build.
16
+ // Otherwise webapp will be compiled in the very slow development mode.
17
+ new webpack.DefinePlugin(env.stringified), // Moment.js is an extremely popular library that bundles large locale files
7
18
  // by default due to how webpack interprets its code. This is a practical
8
19
  // solution that requires the user to opt into importing specific locales.
9
20
  // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
@@ -4,9 +4,7 @@ import getCommonConfig from './common.js';
4
4
  function getDevConfig(webpack, scripts) {
5
5
  return merge(getCommonConfig(webpack, scripts), {
6
6
  mode: 'development',
7
- plugins: [new webpack.DefinePlugin({
8
- 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
9
- }), // This is necessary to emit hot updates
7
+ plugins: [// This is necessary to emit hot updates
10
8
  new webpack.HotModuleReplacementPlugin()],
11
9
  devtool: scripts.sourceMap ? scripts.sourceMap : 'eval-cheap-module-source-map'
12
10
  });
@@ -0,0 +1,67 @@
1
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
2
+
3
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
+
5
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+
7
+ import dotenv from 'dotenv';
8
+ import dotenvExpand from 'dotenv-expand';
9
+ const NODE_ENV = process.env.NODE_ENV;
10
+
11
+ if (!NODE_ENV) {
12
+ throw new Error('The NODE_ENV environment variable is required but was not specified.');
13
+ }
14
+
15
+ const dotenvFile = BalmJS.file.resolveApp('.env'); // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
16
+
17
+ const dotenvFiles = [`${dotenvFile}.${NODE_ENV}.local`, // Don't include `.env.local` for `test` environment
18
+ // since normally you expect tests to produce the same
19
+ // results for everyone
20
+ NODE_ENV !== 'test' && `${dotenvFile}.local`, `${dotenvFile}.${NODE_ENV}`, dotenvFile].filter(Boolean); // Load environment variables from .env* files. Suppress warnings using silent
21
+ // if this file is missing. dotenv will never modify any environment variables
22
+ // that have already been set. Variable expansion is supported in .env files.
23
+ // https://github.com/motdotla/dotenv
24
+ // https://github.com/motdotla/dotenv-expand
25
+
26
+ dotenvFiles.forEach(dotenvFile => {
27
+ if (node.fs.existsSync(dotenvFile)) {
28
+ dotenvExpand.expand(dotenv.config({
29
+ path: dotenvFile
30
+ }));
31
+ }
32
+ }); // Grab NODE_ENV and BALM_APP_* environment variables and prepare them to be
33
+ // injected into the application via DefinePlugin in webpack configuration.
34
+
35
+ const BALM_APP = /^BALM_APP_/i;
36
+
37
+ function getClientEnvironment(publicUrl) {
38
+ const raw = Object.keys(process.env).filter(key => BALM_APP.test(key)).reduce((env, key) => {
39
+ env[key] = process.env[key];
40
+ return env;
41
+ }, _objectSpread({
42
+ // Useful for determining whether we’re running in production mode.
43
+ // Most importantly, it switches webapp into the correct mode.
44
+ NODE_ENV: process.env.NODE_ENV || 'development',
45
+ // Useful for resolving the correct path to static assets in `public`.
46
+ // For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
47
+ // This should only be used as an escape hatch. Normally you would put
48
+ // images into the `src` and `import` them in code to get their paths.
49
+ PUBLIC_URL: publicUrl
50
+ }, BalmJS.config.scripts.nodeEnv)); // Stringify all values so we can feed into webpack DefinePlugin
51
+
52
+ const stringified = {
53
+ 'process.env': Object.keys(raw).reduce((env, key) => {
54
+ env[key] = JSON.stringify(raw[key]);
55
+ return env;
56
+ }, {})
57
+ };
58
+ BalmJS.logger.debug('webpack .env', stringified, {
59
+ pre: true
60
+ });
61
+ return {
62
+ raw,
63
+ stringified
64
+ };
65
+ }
66
+
67
+ export default getClientEnvironment;
@@ -29,9 +29,7 @@ function getProdConfig(webpack, scripts) {
29
29
  extractComments: false
30
30
  }), new CssMinimizerPlugin()]
31
31
  },
32
- plugins: [new webpack.DefinePlugin({
33
- 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production')
34
- }), // Extract css into its own file
32
+ plugins: [// Extract css into its own file
35
33
  ...(scripts.extractCss ? [new MiniCssExtractPlugin({
36
34
  filename: BalmJS.file.assetsPath(getCssFilename()),
37
35
  chunkFilename: BalmJS.file.assetsPath(getCssFilename())
@@ -4,7 +4,7 @@ const cssModuleRegex = /\.module\.css$/;
4
4
  const sassRegex = /\.(scss|sass)$/;
5
5
  const sassModuleRegex = /\.module\.(scss|sass)$/;
6
6
  const jsRegex = /\.(js|mjs|jsx|ts|tsx)$/;
7
- const imgRegex = /\.(bmp|gif|jpe?g|png|svg)(\?.*)?$/;
7
+ const imgRegex = /\.(bmp|gif|jpe?g|png|svg|webp)(\?.*)?$/;
8
8
  const fontRegex = /\.(woff2?|eot|ttf|otf)(\?.*)?$/;
9
9
  const mediaRegex = /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/;
10
10
  export { htmlRegex, cssRegex, cssModuleRegex, sassRegex, sassModuleRegex, jsRegex, imgRegex, fontRegex, mediaRegex };
@@ -7,7 +7,12 @@ function assetLoader() {
7
7
  // A missing `test` is equivalent to a match.
8
8
  {
9
9
  test: imgRegex,
10
- type: 'asset/resource',
10
+ type: BalmJS.config.scripts.imageAssetType,
11
+ parser: {
12
+ dataUrlCondition: {
13
+ maxSize: BalmJS.config.scripts.imageInlineSizeLimit
14
+ }
15
+ },
11
16
  generator: {
12
17
  filename: BalmJS.file.assetsPath(`${ASSET.dir}/${BalmJS.config.paths.target.img}/[name].${ASSET.hash}[ext]`)
13
18
  }
@@ -1,7 +1,12 @@
1
1
  import { jsRegex } from '../config/regex.js';
2
2
 
3
3
  function jsLoader() {
4
- const options = Object.assign({}, BalmJS.config.scripts.babelLoaderOptions); // Process application JS with Babel.
4
+ const options = Object.assign({
5
+ // This is a feature of `babel-loader` for webpack (not Babel itself).
6
+ // It enables caching results in ./node_modules/.cache/babel-loader/
7
+ // directory for faster rebuilds.
8
+ cacheDirectory: true
9
+ }, BalmJS.config.scripts.babelLoaderOptions); // Process application JS with Babel.
5
10
  // The preset includes JSX, Flow, TypeScript, and some ESnext features.
6
11
 
7
12
  return {
@@ -3,8 +3,8 @@ import cssLoader from './css.js';
3
3
  import htmlLoader from './html.js';
4
4
  import assetLoader from './asset.js';
5
5
  export default {
6
- jsLoader,
7
- cssLoader,
6
+ assetLoader,
8
7
  htmlLoader,
9
- assetLoader
8
+ jsLoader,
9
+ cssLoader
10
10
  };
@@ -68,17 +68,21 @@ const babelLoaderOptions = {};
68
68
 
69
69
  const postcssLoaderOptions = {};
70
70
  /**
71
- * Templating: html-loader options
71
+ * Template: html-loader options
72
72
  *
73
73
  * @reference https://github.com/webpack-contrib/html-loader#options
74
74
  */
75
75
 
76
- const htmlLoaderOptions = {}; // Resolve
76
+ const htmlLoaderOptions = {};
77
+ const imageAssetType = 'asset';
78
+ const imageInlineSizeLimit = 8096; // 8kb
79
+ // Resolve
77
80
 
78
81
  const extensions = [];
79
82
  const alias = {}; // Plugins
80
83
 
81
84
  const plugins = [];
85
+ const nodeEnv = {};
82
86
  const injectHtml = false;
83
87
  const htmlPluginOptions = {};
84
88
  const extractCss = false; // Devtool
@@ -123,7 +127,6 @@ const ie8 = false;
123
127
 
124
128
  const inputOptions = {};
125
129
  const outputOptions = {};
126
- const watchOptions = {};
127
130
  /**
128
131
  * Esbuild bundler
129
132
  */
@@ -147,9 +150,12 @@ export default {
147
150
  babelLoaderOptions,
148
151
  postcssLoaderOptions,
149
152
  htmlLoaderOptions,
153
+ imageAssetType,
154
+ imageInlineSizeLimit,
150
155
  extensions,
151
156
  alias,
152
157
  plugins,
158
+ nodeEnv,
153
159
  injectHtml,
154
160
  htmlPluginOptions,
155
161
  extractCss,
@@ -165,7 +171,6 @@ export default {
165
171
  // rollup
166
172
  inputOptions,
167
173
  outputOptions,
168
- watchOptions,
169
174
  // esbuild
170
175
  buildOptions,
171
176
  useTransform,
@@ -1,6 +1,7 @@
1
1
  const extname = 'css';
2
2
  const minify = false;
3
3
  const atImportPaths = [];
4
+ const entry = '';
4
5
  /**
5
6
  * Cssnano optimisations
6
7
  *
@@ -61,6 +62,7 @@ export default {
61
62
  extname,
62
63
  minify,
63
64
  atImportPaths,
65
+ entry,
64
66
  options,
65
67
  sassOptions,
66
68
  lessOptions,
package/lib/hello.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { versions } from 'node:process';
1
2
  import { createRequire } from 'node:module';
2
3
  import fs from 'node:fs';
3
4
  import { URL } from 'node:url';
@@ -8,8 +9,13 @@ const balmCorePkg = JSON.parse(fs.readFileSync(new URL('../package.json', import
8
9
  global.requireModule = requireModule;
9
10
  global.BalmJS = {
10
11
  version: balmCorePkg.version,
11
- emitter: new EventEmitter()
12
+ emitter: new EventEmitter(),
13
+ useCacache: +versions.node.split('.')[0] >= 18
12
14
  };
13
- BalmJS.loading = true;
14
- cacheBalmCore();
15
+
16
+ if (!BalmJS.useCacache) {
17
+ BalmJS.loading = true;
18
+ cacheBalmCore();
19
+ }
20
+
15
21
  export default balmCorePkg.version;
@@ -1,4 +1,4 @@
1
- // Reference `gulp-rename@5.1.0`
1
+ // Reference `gulp-sass@5.1.0`
2
2
  import { Transform } from 'node:stream';
3
3
  import sass from 'sass';
4
4
  import replaceExtension from 'replace-ext';
@@ -32,7 +32,7 @@ const filePush = (file, sassObject, callback) => {
32
32
  const sourceFileIndex = sassMap.sources.indexOf(sassMapFile); // Prepend the path to all files in the sources array except the file that's being worked on
33
33
 
34
34
  sassMap.sources = sassMap.sources.map((source, index) => index === sourceFileIndex ? source : node.path.join(sassFileSrcPath, source));
35
- } // Remove 'stdin' from souces and replace with filenames!
35
+ } // Remove 'stdin' from sources and replace with filenames!
36
36
 
37
37
 
38
38
  sassMap.sources = sassMap.sources.filter(src => src !== 'stdin' && src); // Replace the map file with the original filename (but new extension)
@@ -19,11 +19,23 @@ class BalmStyleTask extends BalmTask {
19
19
  extname = 'css';
20
20
  }
21
21
 
22
- this.defaultInput = node.path.join(BalmJS.config.src.css, '**', `!(_*).${extname}`);
22
+ if (Array.isArray(BalmJS.config.styles.entry)) {
23
+ this.defaultInput = BalmJS.config.styles.entry.map(styleEntry => node.path.join(BalmJS.config.src.css, styleEntry));
24
+ } else {
25
+ if (BalmJS.config.styles.entry) {
26
+ this.defaultInput = node.path.join(BalmJS.config.src.css, BalmJS.config.styles.entry);
27
+ } else {
28
+ this.defaultInput = node.path.join(BalmJS.config.src.css, '**', `!(_*).${extname}`);
29
+ }
30
+ }
31
+
23
32
  this.defaultOutput = BalmJS.config.env.isMP ? node.path.join(BalmJS.config.dest.base, ASSET.mpDir, BalmJS.config.paths.target.css) : BalmJS.config.dest.css;
24
33
  }
25
34
 
26
35
  handleStyle(style, output, options) {
36
+ BalmJS.logger.debug(`${this.name} entry`, this.defaultInput, {
37
+ pre: true
38
+ });
27
39
  const taskName = `${this.name} task`;
28
40
  const shouldUseSourceMap = !(BalmJS.config.env.isProd || BalmJS.config.styles.minify);
29
41
  let stream = gulp.src(this.input, Object.assign({
@@ -25,13 +25,13 @@ class BalmCompiling {
25
25
  }
26
26
 
27
27
  start() {
28
- if (_classPrivateFieldGet(this, _firstCompile)) {
28
+ if (!BalmJS.useCacache && _classPrivateFieldGet(this, _firstCompile)) {
29
29
  loading.render('Compiling to JS...');
30
30
  }
31
31
  }
32
32
 
33
33
  stop() {
34
- if (_classPrivateFieldGet(this, _firstCompile)) {
34
+ if (!BalmJS.useCacache && _classPrivateFieldGet(this, _firstCompile)) {
35
35
  _classPrivateFieldSet(this, _firstCompile, false);
36
36
 
37
37
  loading.clear();
@@ -3,9 +3,11 @@ import { PUBLIC_URL } from '../config/constants.js'; // Make sure any symlinks i
3
3
 
4
4
  const appDirectory = node.fs.realpathSync(process.cwd());
5
5
 
6
- const resolveApp = relativePath => node.path.resolve(appDirectory, relativePath);
7
-
8
6
  class File {
7
+ resolveApp(relativePath) {
8
+ return node.path.resolve(appDirectory, relativePath);
9
+ }
10
+
9
11
  get publicUrlOrPath() {
10
12
  // We use `PUBLIC_URL` environment variable or "homepage" field to infer
11
13
  // "public path" at which the app is served.
@@ -13,7 +15,7 @@ class File {
13
15
  // single-page apps that may serve index.html for nested URLs like /todos/42.
14
16
  // We can't use a relative path in HTML because we don't want to load something
15
17
  // like /todos/42/static/js/bundle.7289d.js. We have to know the root.
16
- return getPublicUrlOrPath(requireModule(resolveApp('package.json')).homepage, process.env.PUBLIC_URL);
18
+ return getPublicUrlOrPath(requireModule(this.resolveApp('package.json')).homepage, process.env.PUBLIC_URL);
17
19
  }
18
20
 
19
21
  get stylePaths() {
@@ -63,7 +63,7 @@ class BalmLoading {
63
63
 
64
64
  succeed() {
65
65
  this.clear();
66
- console.log(`BalmJS version: ${BalmJS.version}`);
66
+ console.log(`BalmJS core version: ${BalmJS.version}`);
67
67
  }
68
68
 
69
69
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "balm-core",
3
- "version": "4.5.5",
3
+ "version": "4.8.0",
4
4
  "description": "BalmJS compiler core",
5
5
  "keywords": [
6
6
  "balm",
@@ -41,17 +41,19 @@
41
41
  "directory": "packages/balm-core"
42
42
  },
43
43
  "dependencies": {
44
- "ansi-colors": "^4.1.1",
44
+ "ansi-colors": "^4.1.3",
45
45
  "async": "^3.2.3",
46
- "autoprefixer": "^10.4.4",
47
- "babel-loader": "^8.2.4",
48
- "browser-sync": "^2.27.9",
46
+ "autoprefixer": "^10.4.7",
47
+ "babel-loader": "^8.2.5",
48
+ "browser-sync": "^2.27.10",
49
49
  "connect-history-api-fallback": "^1.6.0",
50
50
  "css-loader": "^6.7.1",
51
- "css-minimizer-webpack-plugin": "^3.4.1",
52
- "cssnano": "^5.1.7",
53
- "del": "^6.0.0",
54
- "esbuild": "^0.14.0",
51
+ "css-minimizer-webpack-plugin": "^4.0.0",
52
+ "cssnano": "^5.1.9",
53
+ "del": "^6.1.1",
54
+ "dotenv": "^16.0.1",
55
+ "dotenv-expand": "^8.0.3",
56
+ "esbuild": "^0.14",
55
57
  "fancy-log": "^2.0.0",
56
58
  "gulp-eslint": "^6.0.0",
57
59
  "gulp-if": "^3.0.0",
@@ -65,7 +67,7 @@
65
67
  "html-loader": "^3.1.0",
66
68
  "html-minifier": "^4.0.0",
67
69
  "html-webpack-plugin": "^5.5.0",
68
- "http-proxy-middleware": "^2.0.4",
70
+ "http-proxy-middleware": "^2.0.6",
69
71
  "imagemin": "^8.0.1",
70
72
  "istextorbinary": "^6.0.0",
71
73
  "less": "^4.1.2",
@@ -73,40 +75,40 @@
73
75
  "modernizr": "^3.12.0",
74
76
  "parents": "^1.0.1",
75
77
  "plugin-error": "^1.0.1",
76
- "postcss": "^8.4.12",
78
+ "postcss": "^8.4.14",
77
79
  "postcss-flexbugs-fixes": "^5.0.2",
78
80
  "postcss-import": "^14.1.0",
79
- "postcss-load-config": "^3.1.4",
80
- "postcss-loader": "6.2.1",
81
- "postcss-preset-env": "^7.4.3",
81
+ "postcss-load-config": "^4.0.0",
82
+ "postcss-loader": "7.0.0",
83
+ "postcss-preset-env": "^7.6.0",
82
84
  "pretty-bytes": "^6.0.0",
83
85
  "readable-stream": "^3.6.0",
84
86
  "replace-ext": "^2.0.0",
85
- "rollup": "^2.70.1",
87
+ "rollup": "^2.75.0",
86
88
  "rollup-plugin-terser": "^7.0.2",
87
- "sass": "^1.50.0",
88
- "sass-loader": "^12.6.0",
89
- "ssh2": "^1.9.0",
89
+ "sass": "^1.52.1",
90
+ "sass-loader": "^13.0.0",
91
+ "ssh2": "^1.10.0",
90
92
  "strip-ansi": "^7.0.1",
91
93
  "style-loader": "^3.3.1",
92
- "terser": "^5.12.1",
94
+ "terser": "^5.13.1",
93
95
  "terser-webpack-plugin": "^5.3.1",
94
96
  "through2": "^4.0.2",
95
97
  "through2-concurrent": "^2.0.0",
96
- "tslib": "^2.3.1",
98
+ "tslib": "^2.4.0",
97
99
  "vinyl-sourcemaps-apply": "^0.2.1",
98
- "webpack": "^5.72.0",
100
+ "webpack": "^5.72.1",
99
101
  "webpack-bundle-analyzer": "^4.5.0",
100
- "webpack-dev-middleware": "^5.3.1",
102
+ "webpack-dev-middleware": "^5.3.3",
101
103
  "webpack-hot-middleware": "^2.25.1",
102
104
  "webpack-merge": "^5.8.0",
103
- "workbox-build": "^6.5.2"
105
+ "workbox-build": "^6.5.3"
104
106
  },
105
107
  "devDependencies": {
106
- "@swc/core": "^1.2.0",
108
+ "@swc/core": "^1.2",
107
109
  "@types/express": "^4.17.13",
108
- "@types/node": "^17.0.23",
109
- "@types/uglify-js": "^3.13.1",
110
+ "@types/node": "^17",
111
+ "@types/uglify-js": "^3.13.2",
110
112
  "@types/webpack": "^5.28.0"
111
113
  },
112
114
  "optionalDependencies": {
@@ -116,7 +118,7 @@
116
118
  "imagemin-svgo": "^9.0.0"
117
119
  },
118
120
  "engines": {
119
- "node": ">=12.13.0"
121
+ "node": ">=14.15.0"
120
122
  },
121
- "gitHead": "182ee55022c6194293195631a91a14bd22cacace"
123
+ "gitHead": "013f70d21057d05acab46caab883b37bb53a0362"
122
124
  }
package/tslib/balm.js CHANGED
@@ -9,9 +9,9 @@ import loading from './utilities/loading.js';
9
9
  class Balm {
10
10
  constructor() {
11
11
  _Balm_config.set(this, void 0);
12
- __classPrivateFieldSet(this, _Balm_config, setConfig({}), "f");
13
12
  BalmJS.loading = false;
14
13
  loading.succeed();
14
+ __classPrivateFieldSet(this, _Balm_config, setConfig({}), "f");
15
15
  }
16
16
  get config() {
17
17
  return __classPrivateFieldGet(this, _Balm_config, "f");
@@ -28,6 +28,7 @@ function checkConfig() {
28
28
  upgradeRenamed('3.16.0', 'scripts', 'inject', 'useCache');
29
29
  upgradeDeprecated('3.17.0', 'styles', 'darkSass');
30
30
  upgradeDeprecated('3.19.0', 'scripts', 'useCache');
31
+ upgradeDeprecated('4.0.0', 'scripts', 'libraryTarget');
31
32
  upgradeDeprecated('4.5.0', 'scripts', 'excludeUrlResource');
32
33
  upgradeDeprecated('4.5.0', 'scripts', 'urlLoaderOptions');
33
34
  }
@@ -1,8 +1,11 @@
1
1
  import HtmlWebpackPlugin from 'html-webpack-plugin';
2
2
  import getLoaders from '../loaders.js';
3
3
  import { CHUNK } from '../../../config/constants.js';
4
+ import getClientEnvironment from './env.js';
4
5
  function getDefaultPlugins(webpack, scripts) {
6
+ const env = getClientEnvironment(BalmJS.file.publicUrlOrPath.slice(0, -1));
5
7
  const plugins = [
8
+ new webpack.DefinePlugin(env.stringified),
6
9
  new webpack.IgnorePlugin({
7
10
  resourceRegExp: /^\.\/locale$/,
8
11
  contextRegExp: /moment$/
@@ -4,9 +4,6 @@ function getDevConfig(webpack, scripts) {
4
4
  return merge(getCommonConfig(webpack, scripts), {
5
5
  mode: 'development',
6
6
  plugins: [
7
- new webpack.DefinePlugin({
8
- 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
9
- }),
10
7
  new webpack.HotModuleReplacementPlugin()
11
8
  ],
12
9
  devtool: scripts.sourceMap
@@ -0,0 +1,44 @@
1
+ import dotenv from 'dotenv';
2
+ import dotenvExpand from 'dotenv-expand';
3
+ const NODE_ENV = process.env.NODE_ENV;
4
+ if (!NODE_ENV) {
5
+ throw new Error('The NODE_ENV environment variable is required but was not specified.');
6
+ }
7
+ const dotenvFile = BalmJS.file.resolveApp('.env');
8
+ const dotenvFiles = [
9
+ `${dotenvFile}.${NODE_ENV}.local`,
10
+ NODE_ENV !== 'test' && `${dotenvFile}.local`,
11
+ `${dotenvFile}.${NODE_ENV}`,
12
+ dotenvFile
13
+ ].filter(Boolean);
14
+ dotenvFiles.forEach((dotenvFile) => {
15
+ if (node.fs.existsSync(dotenvFile)) {
16
+ dotenvExpand.expand(dotenv.config({
17
+ path: dotenvFile
18
+ }));
19
+ }
20
+ });
21
+ const BALM_APP = /^BALM_APP_/i;
22
+ function getClientEnvironment(publicUrl) {
23
+ const raw = Object.keys(process.env)
24
+ .filter((key) => BALM_APP.test(key))
25
+ .reduce((env, key) => {
26
+ env[key] = process.env[key];
27
+ return env;
28
+ }, {
29
+ NODE_ENV: process.env.NODE_ENV || 'development',
30
+ PUBLIC_URL: publicUrl,
31
+ ...BalmJS.config.scripts.nodeEnv
32
+ });
33
+ const stringified = {
34
+ 'process.env': Object.keys(raw).reduce((env, key) => {
35
+ env[key] = JSON.stringify(raw[key]);
36
+ return env;
37
+ }, {})
38
+ };
39
+ BalmJS.logger.debug('webpack .env', stringified, {
40
+ pre: true
41
+ });
42
+ return { raw, stringified };
43
+ }
44
+ export default getClientEnvironment;
@@ -25,9 +25,6 @@ function getProdConfig(webpack, scripts) {
25
25
  ]
26
26
  },
27
27
  plugins: [
28
- new webpack.DefinePlugin({
29
- 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production')
30
- }),
31
28
  ...(scripts.extractCss
32
29
  ? [
33
30
  new MiniCssExtractPlugin({
@@ -4,7 +4,7 @@ const cssModuleRegex = /\.module\.css$/;
4
4
  const sassRegex = /\.(scss|sass)$/;
5
5
  const sassModuleRegex = /\.module\.(scss|sass)$/;
6
6
  const jsRegex = /\.(js|mjs|jsx|ts|tsx)$/;
7
- const imgRegex = /\.(bmp|gif|jpe?g|png|svg)(\?.*)?$/;
7
+ const imgRegex = /\.(bmp|gif|jpe?g|png|svg|webp)(\?.*)?$/;
8
8
  const fontRegex = /\.(woff2?|eot|ttf|otf)(\?.*)?$/;
9
9
  const mediaRegex = /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/;
10
10
  export { htmlRegex, cssRegex, cssModuleRegex, sassRegex, sassModuleRegex, jsRegex, imgRegex, fontRegex, mediaRegex };
@@ -4,7 +4,12 @@ function assetLoader() {
4
4
  return [
5
5
  {
6
6
  test: imgRegex,
7
- type: 'asset/resource',
7
+ type: BalmJS.config.scripts.imageAssetType,
8
+ parser: {
9
+ dataUrlCondition: {
10
+ maxSize: BalmJS.config.scripts.imageInlineSizeLimit
11
+ }
12
+ },
8
13
  generator: {
9
14
  filename: BalmJS.file.assetsPath(`${ASSET.dir}/${BalmJS.config.paths.target.img}/[name].${ASSET.hash}[ext]`)
10
15
  }
@@ -1,6 +1,8 @@
1
1
  import { jsRegex } from '../config/regex.js';
2
2
  function jsLoader() {
3
- const options = Object.assign({}, BalmJS.config.scripts.babelLoaderOptions);
3
+ const options = Object.assign({
4
+ cacheDirectory: true
5
+ }, BalmJS.config.scripts.babelLoaderOptions);
4
6
  return {
5
7
  test: jsRegex,
6
8
  include: [
@@ -3,8 +3,8 @@ import cssLoader from './css.js';
3
3
  import htmlLoader from './html.js';
4
4
  import assetLoader from './asset.js';
5
5
  export default {
6
- jsLoader,
7
- cssLoader,
6
+ assetLoader,
8
7
  htmlLoader,
9
- assetLoader
8
+ jsLoader,
9
+ cssLoader
10
10
  };
@@ -27,9 +27,12 @@ const useEsModule = true;
27
27
  const babelLoaderOptions = {};
28
28
  const postcssLoaderOptions = {};
29
29
  const htmlLoaderOptions = {};
30
+ const imageAssetType = 'asset';
31
+ const imageInlineSizeLimit = 8096;
30
32
  const extensions = [];
31
33
  const alias = {};
32
34
  const plugins = [];
35
+ const nodeEnv = {};
33
36
  const injectHtml = false;
34
37
  const htmlPluginOptions = {};
35
38
  const extractCss = false;
@@ -50,7 +53,6 @@ const vendorName = 'vendor';
50
53
  const ie8 = false;
51
54
  const inputOptions = {};
52
55
  const outputOptions = {};
53
- const watchOptions = {};
54
56
  const buildOptions = {};
55
57
  const useTransform = false;
56
58
  const transformOptions = {};
@@ -68,9 +70,12 @@ export default {
68
70
  babelLoaderOptions,
69
71
  postcssLoaderOptions,
70
72
  htmlLoaderOptions,
73
+ imageAssetType,
74
+ imageInlineSizeLimit,
71
75
  extensions,
72
76
  alias,
73
77
  plugins,
78
+ nodeEnv,
74
79
  injectHtml,
75
80
  htmlPluginOptions,
76
81
  extractCss,
@@ -85,7 +90,6 @@ export default {
85
90
  ie8,
86
91
  inputOptions,
87
92
  outputOptions,
88
- watchOptions,
89
93
  buildOptions,
90
94
  useTransform,
91
95
  transformOptions
@@ -1,6 +1,7 @@
1
1
  const extname = 'css';
2
2
  const minify = false;
3
3
  const atImportPaths = [];
4
+ const entry = '';
4
5
  const options = {
5
6
  discardComments: {
6
7
  removeAll: true
@@ -23,6 +24,7 @@ export default {
23
24
  extname,
24
25
  minify,
25
26
  atImportPaths,
27
+ entry,
26
28
  options,
27
29
  sassOptions,
28
30
  lessOptions,
package/tslib/hello.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { versions } from 'node:process';
1
2
  import { createRequire } from 'node:module';
2
3
  import fs from 'node:fs';
3
4
  import { URL } from 'node:url';
@@ -8,8 +9,11 @@ const balmCorePkg = JSON.parse(fs.readFileSync(new URL('../package.json', import
8
9
  global.requireModule = requireModule;
9
10
  global.BalmJS = {
10
11
  version: balmCorePkg.version,
11
- emitter: new EventEmitter()
12
+ emitter: new EventEmitter(),
13
+ useCacache: +versions.node.split('.')[0] >= 18
12
14
  };
13
- BalmJS.loading = true;
14
- cacheBalmCore();
15
+ if (!BalmJS.useCacache) {
16
+ BalmJS.loading = true;
17
+ cacheBalmCore();
18
+ }
15
19
  export default balmCorePkg.version;
@@ -14,12 +14,25 @@ class BalmStyleTask extends BalmTask {
14
14
  default:
15
15
  extname = 'css';
16
16
  }
17
- this.defaultInput = node.path.join(BalmJS.config.src.css, '**', `!(_*).${extname}`);
17
+ if (Array.isArray(BalmJS.config.styles.entry)) {
18
+ this.defaultInput = BalmJS.config.styles.entry.map((styleEntry) => node.path.join(BalmJS.config.src.css, styleEntry));
19
+ }
20
+ else {
21
+ if (BalmJS.config.styles.entry) {
22
+ this.defaultInput = node.path.join(BalmJS.config.src.css, BalmJS.config.styles.entry);
23
+ }
24
+ else {
25
+ this.defaultInput = node.path.join(BalmJS.config.src.css, '**', `!(_*).${extname}`);
26
+ }
27
+ }
18
28
  this.defaultOutput = BalmJS.config.env.isMP
19
29
  ? node.path.join(BalmJS.config.dest.base, ASSET.mpDir, BalmJS.config.paths.target.css)
20
30
  : BalmJS.config.dest.css;
21
31
  }
22
32
  handleStyle(style, output, options) {
33
+ BalmJS.logger.debug(`${this.name} entry`, this.defaultInput, {
34
+ pre: true
35
+ });
23
36
  const taskName = `${this.name} task`;
24
37
  const shouldUseSourceMap = !(BalmJS.config.env.isProd || BalmJS.config.styles.minify);
25
38
  let stream = gulp
@@ -6,12 +6,12 @@ class BalmCompiling {
6
6
  _BalmCompiling_firstCompile.set(this, true);
7
7
  }
8
8
  start() {
9
- if (__classPrivateFieldGet(this, _BalmCompiling_firstCompile, "f")) {
9
+ if (!BalmJS.useCacache && __classPrivateFieldGet(this, _BalmCompiling_firstCompile, "f")) {
10
10
  loading.render('Compiling to JS...');
11
11
  }
12
12
  }
13
13
  stop() {
14
- if (__classPrivateFieldGet(this, _BalmCompiling_firstCompile, "f")) {
14
+ if (!BalmJS.useCacache && __classPrivateFieldGet(this, _BalmCompiling_firstCompile, "f")) {
15
15
  __classPrivateFieldSet(this, _BalmCompiling_firstCompile, false, "f");
16
16
  loading.clear();
17
17
  }
@@ -1,10 +1,12 @@
1
1
  import getPublicUrlOrPath from './public-url.js';
2
2
  import { PUBLIC_URL } from '../config/constants.js';
3
3
  const appDirectory = node.fs.realpathSync(process.cwd());
4
- const resolveApp = (relativePath) => node.path.resolve(appDirectory, relativePath);
5
4
  class File {
5
+ resolveApp(relativePath) {
6
+ return node.path.resolve(appDirectory, relativePath);
7
+ }
6
8
  get publicUrlOrPath() {
7
- return getPublicUrlOrPath(requireModule(resolveApp('package.json'))
9
+ return getPublicUrlOrPath(requireModule(this.resolveApp('package.json'))
8
10
  .homepage, process.env.PUBLIC_URL);
9
11
  }
10
12
  get stylePaths() {
@@ -24,7 +24,7 @@ class BalmLoading {
24
24
  }
25
25
  succeed() {
26
26
  this.clear();
27
- console.log(`BalmJS version: ${BalmJS.version}`);
27
+ console.log(`BalmJS core version: ${BalmJS.version}`);
28
28
  }
29
29
  }
30
30
  _BalmLoading_stream = new WeakMap(), _BalmLoading_frameIndex = new WeakMap(), _BalmLoading_frameCount = new WeakMap();