@enact/cli 5.0.0-alpha.5 → 5.0.1
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/.travis.yml +3 -5
- package/CHANGELOG.md +29 -0
- package/README.md +16 -2
- package/commands/pack.js +7 -5
- package/commands/serve.js +50 -30
- package/config/dotenv.js +1 -1
- package/config/jest/jest.config.js +4 -4
- package/config/webpack.config.js +61 -30
- package/docs/building-apps.md +92 -0
- package/docs/isomorphic-support.md +26 -0
- package/npm-shrinkwrap.json +9265 -7643
- package/package.json +49 -49
package/.travis.yml
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
## 5.0.1 (August 30, 2022)
|
|
2
|
+
|
|
3
|
+
### pack
|
|
4
|
+
|
|
5
|
+
* Updated @enact/dev-utils fixing isomorphic build with the latest language list.
|
|
6
|
+
* Fixed Enact project setting `forceCSSModules` to enforce modular CSS.
|
|
7
|
+
|
|
8
|
+
## 5.0.0 (July 19, 2022)
|
|
9
|
+
|
|
10
|
+
* Updated dependencies.
|
|
11
|
+
|
|
12
|
+
### pack
|
|
13
|
+
|
|
14
|
+
* Fixed build failure when `.env` file exists.
|
|
15
|
+
* Fixed `snapshot_blob.bin` file is not listed on the build results.
|
|
16
|
+
|
|
17
|
+
## 5.0.0-rc.1 (Jun 23, 2022)
|
|
18
|
+
|
|
19
|
+
### serve
|
|
20
|
+
|
|
21
|
+
* Fixed `enact serve` fails to open another port when the default port is busy.
|
|
22
|
+
|
|
23
|
+
### pack
|
|
24
|
+
|
|
25
|
+
* Fixed `core-js` version to `3.22.8` for compatibility.
|
|
26
|
+
* Added `ENACT_PACK_ISOMORPHIC` as a global variable to use `hydrateRoot` instead of `createRoot` from app when isomorphic build.
|
|
27
|
+
* Added `ignoreWarning` config to ignore warnings from SnapshotPlugin.
|
|
28
|
+
* Updated webpack config to support `sass-loader` for opt-in support of SASS/SCSS files.
|
|
29
|
+
|
|
1
30
|
## 5.0.0-alpha.5 (May 31, 2022)
|
|
2
31
|
|
|
3
32
|
* Updated the `lockfileVersion` of npm-shrinkwrap file to v2.
|
package/README.md
CHANGED
|
@@ -92,7 +92,6 @@ For example:
|
|
|
92
92
|
}
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
-
|
|
96
95
|
## Displaying Lint Output in the Editor
|
|
97
96
|
|
|
98
97
|
Some editors, including Sublime Text, Atom, and Visual Studio Code, provide plugins for ESLint.
|
|
@@ -104,6 +103,21 @@ You would need to install an ESLint plugin for your editor first.
|
|
|
104
103
|
Ever since ESLint 6, global installs of ESLint configs are no longer supported.
|
|
105
104
|
To work around this new limitation, while still supporting in-editor linting, we've created a new [eslint-config-enact-proxy](https://github.com/enactjs/eslint-config-enact-proxy) package.
|
|
106
105
|
The [eslint-config-enact-proxy](https://github.com/enactjs/eslint-config-enact-proxy) acts like a small proxy config, redirecting ESLint to use a globally-installed Enact ESLint config.
|
|
106
|
+
`eslint-config-enact-proxy` needs to be installed locally on a project to enable in-editor linting:
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
npm install --save-dev eslint-config-enact-proxy
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Also, you need to modify `eslintConfig` property in `package.json`:
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
"eslintConfig": {
|
|
116
|
+
"extends": "enact-proxy"
|
|
117
|
+
},
|
|
118
|
+
```
|
|
119
|
+
>**NOTE**: For strict mode, use `"extends": "enact-proxy/strict"`.
|
|
120
|
+
|
|
107
121
|
In order for in-editor linting to work with our updated ESLint config, you'll need to upgrade to ESLint 7 or later. This can be installed globally by running:
|
|
108
122
|
|
|
109
123
|
```sh
|
|
@@ -113,7 +127,7 @@ npm install -g eslint
|
|
|
113
127
|
Then, you will need to uninstall any previous globally-installed Enact linting package (everything but eslint itself):
|
|
114
128
|
|
|
115
129
|
```sh
|
|
116
|
-
npm
|
|
130
|
+
npm uninstall -g eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-babel @babel/eslint-parser eslint-plugin-jest eslint-plugin-enact eslint-config-enact
|
|
117
131
|
```
|
|
118
132
|
|
|
119
133
|
## Copyright and License Information
|
package/commands/pack.js
CHANGED
|
@@ -19,7 +19,7 @@ const minimist = require('minimist');
|
|
|
19
19
|
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
|
|
20
20
|
const printBuildError = require('react-dev-utils/printBuildError');
|
|
21
21
|
const stripAnsi = require('strip-ansi');
|
|
22
|
-
const
|
|
22
|
+
const webpack = require('webpack');
|
|
23
23
|
const {optionParser: app, mixins, configHelper: helper} = require('@enact/dev-utils');
|
|
24
24
|
|
|
25
25
|
function displayHelp() {
|
|
@@ -147,7 +147,7 @@ function copyPublicFolder(output) {
|
|
|
147
147
|
// Print a detailed summary of build files.
|
|
148
148
|
function printFileSizes(stats, output) {
|
|
149
149
|
const assets = stats
|
|
150
|
-
.toJson({all: false, assets: true})
|
|
150
|
+
.toJson({all: false, assets: true, cachedAssets: true})
|
|
151
151
|
.assets.filter(asset => /\.(js|css|bin)$/.test(asset.name))
|
|
152
152
|
.map(asset => {
|
|
153
153
|
const size = fs.statSync(path.join(output, asset.name)).size;
|
|
@@ -250,7 +250,11 @@ function api(opts = {}) {
|
|
|
250
250
|
|
|
251
251
|
// Do this as the first thing so that any code reading it knows the right env.
|
|
252
252
|
const configFactory = require('../config/webpack.config');
|
|
253
|
-
const config = configFactory(
|
|
253
|
+
const config = configFactory(
|
|
254
|
+
opts.production ? 'production' : 'development',
|
|
255
|
+
opts.isomorphic,
|
|
256
|
+
opts['ilib-additional-path']
|
|
257
|
+
);
|
|
254
258
|
|
|
255
259
|
// Set any entry path override
|
|
256
260
|
if (opts.entry) helper.replaceMain(config, path.resolve(opts.entry));
|
|
@@ -258,8 +262,6 @@ function api(opts = {}) {
|
|
|
258
262
|
// Set any output path override
|
|
259
263
|
if (opts.output) config.output.path = path.resolve(opts.output);
|
|
260
264
|
|
|
261
|
-
if (opts.verbose) opts.ProgressPlugin = ProgressPlugin;
|
|
262
|
-
|
|
263
265
|
mixins.apply(config, opts);
|
|
264
266
|
|
|
265
267
|
// Remove all content but keep the directory so that
|
package/commands/serve.js
CHANGED
|
@@ -93,7 +93,7 @@ function hotDevServer(config, fastRefresh) {
|
|
|
93
93
|
return config;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
function devServerConfig(host, protocol, publicPath, proxy, allowedHost) {
|
|
96
|
+
function devServerConfig(host, port, protocol, publicPath, proxy, allowedHost) {
|
|
97
97
|
let https = false;
|
|
98
98
|
const {SSL_CRT_FILE, SSL_KEY_FILE} = process.env;
|
|
99
99
|
if (protocol === 'https' && [SSL_CRT_FILE, SSL_KEY_FILE].every(f => f && fs.existsSync(f))) {
|
|
@@ -127,38 +127,59 @@ function devServerConfig(host, protocol, publicPath, proxy, allowedHost) {
|
|
|
127
127
|
// Enable HTTPS if the HTTPS environment variable is set to 'true'
|
|
128
128
|
https,
|
|
129
129
|
host,
|
|
130
|
+
port,
|
|
130
131
|
// Allow cross-origin HTTP requests
|
|
131
132
|
headers: {
|
|
132
133
|
'Access-Control-Allow-Origin': '*',
|
|
133
134
|
'Access-Control-Allow-Methods': '*',
|
|
134
135
|
'Access-Control-Allow-Headers': '*'
|
|
135
136
|
},
|
|
136
|
-
static:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
137
|
+
static: [
|
|
138
|
+
{
|
|
139
|
+
// By default WebpackDevServer serves physical files from current directory
|
|
140
|
+
// in addition to all the virtual build products that it serves from memory.
|
|
141
|
+
// This is confusing because those files won’t automatically be available in
|
|
142
|
+
// production build folder unless we copy them. However, copying the whole
|
|
143
|
+
// project directory is dangerous because we may expose sensitive files.
|
|
144
|
+
// Instead, we establish a convention that only files in `public` directory
|
|
145
|
+
// get served. Our build script will copy `public` into the `build` folder.
|
|
146
|
+
// In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%:
|
|
147
|
+
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
|
|
148
|
+
// In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
|
|
149
|
+
// Note that we only recommend to use `public` folder as an escape hatch
|
|
150
|
+
// for files like `favicon.ico`, `manifest.json`, and libraries that are
|
|
151
|
+
// for some reason broken when imported through webpack. If you just want to
|
|
152
|
+
// use an image, put it in `src` and `import` it from JavaScript instead.
|
|
153
|
+
directory: path.resolve(app.context, 'public'),
|
|
154
|
+
publicPath,
|
|
155
|
+
// By default files from `contentBase` will not trigger a page reload.
|
|
156
|
+
watch: {
|
|
157
|
+
// Reportedly, this avoids CPU overload on some systems.
|
|
158
|
+
// https://github.com/facebook/create-react-app/issues/293
|
|
159
|
+
// src/node_modules is not ignored to support absolute imports
|
|
160
|
+
// https://github.com/facebook/create-react-app/issues/1065
|
|
161
|
+
ignored: [
|
|
162
|
+
ignoredFiles(path.resolve(app.context, 'src')),
|
|
163
|
+
'/node_modules[\\/](?!@enact[\\/](?!.*node_modules))/'
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
directory: path.resolve(app.context, '__mocks__'),
|
|
169
|
+
publicPath,
|
|
170
|
+
// By default files from `contentBase` will not trigger a page reload.
|
|
171
|
+
watch: {
|
|
172
|
+
// Reportedly, this avoids CPU overload on some systems.
|
|
173
|
+
// https://github.com/facebook/create-react-app/issues/293
|
|
174
|
+
// src/node_modules is not ignored to support absolute imports
|
|
175
|
+
// https://github.com/facebook/create-react-app/issues/1065
|
|
176
|
+
ignored: [
|
|
177
|
+
ignoredFiles(path.resolve(app.context, 'src')),
|
|
178
|
+
'/node_modules[\\/](?!@enact[\\/](?!.*node_modules))/'
|
|
179
|
+
]
|
|
180
|
+
}
|
|
160
181
|
}
|
|
161
|
-
|
|
182
|
+
],
|
|
162
183
|
client: {
|
|
163
184
|
webSocketURL: {
|
|
164
185
|
// Enable custom sockjs pathname for websocket connection to hot reloading server.
|
|
@@ -249,8 +270,7 @@ function serve(config, host, port, open) {
|
|
|
249
270
|
// Serve webpack assets generated by the compiler over a web sever.
|
|
250
271
|
const serverConfig = Object.assign(
|
|
251
272
|
{},
|
|
252
|
-
|
|
253
|
-
devServerConfig(host, protocol, publicPath, proxyConfig, urls.lanUrlForConfig)
|
|
273
|
+
devServerConfig(host, resolvedPort, protocol, publicPath, proxyConfig, urls.lanUrlForConfig)
|
|
254
274
|
);
|
|
255
275
|
const devServer = new WebpackDevServer(serverConfig, compiler);
|
|
256
276
|
// Launch WebpackDevServer.
|
|
@@ -304,8 +324,8 @@ function api(opts) {
|
|
|
304
324
|
const config = hotDevServer(configFactory('development'), fastRefresh);
|
|
305
325
|
|
|
306
326
|
// Tools like Cloud9 rely on this.
|
|
307
|
-
const host = process.env.HOST || opts.host ||
|
|
308
|
-
const port = parseInt(process.env.PORT || opts.port ||
|
|
327
|
+
const host = process.env.HOST || opts.host || '0.0.0.0';
|
|
328
|
+
const port = parseInt(process.env.PORT || opts.port || 8080);
|
|
309
329
|
|
|
310
330
|
// Start serving
|
|
311
331
|
if (['node', 'async-node', 'webworker'].includes(app.environment)) {
|
package/config/dotenv.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const dotenv = require('dotenv');
|
|
6
|
-
const expand = require('dotenv-expand');
|
|
6
|
+
const {expand} = require('dotenv-expand');
|
|
7
7
|
|
|
8
8
|
// Loads all required .env files in correct order, for a given mode.
|
|
9
9
|
// See https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
|
|
@@ -76,15 +76,15 @@ module.exports = {
|
|
|
76
76
|
testURL: 'http://localhost',
|
|
77
77
|
transform: {
|
|
78
78
|
'^.+\\.(js|jsx|ts|tsx)$': require.resolve('./babelTransform'),
|
|
79
|
-
'^.+\\.(css|less)$': require.resolve('./cssTransform.js'),
|
|
80
|
-
'^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|less|json)$)': require.resolve('./fileTransform')
|
|
79
|
+
'^.+\\.(css|less|sass|scss)$': require.resolve('./cssTransform.js'),
|
|
80
|
+
'^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|less|sass|scss|json)$)': require.resolve('./fileTransform')
|
|
81
81
|
},
|
|
82
82
|
transformIgnorePatterns: [
|
|
83
83
|
'[/\\\\]node_modules[/\\\\](?!@enact).+\\.(js|jsx|mjs|cjs|ts|tsx)$',
|
|
84
|
-
'^.+\\.module\\.(css|less)$'
|
|
84
|
+
'^.+\\.module\\.(css|less|sass|scss)$'
|
|
85
85
|
],
|
|
86
86
|
moduleNameMapper: {
|
|
87
|
-
'^.+\\.module\\.(css|less)$': require.resolve('identity-obj-proxy'),
|
|
87
|
+
'^.+\\.module\\.(css|less|sass|scss)$': require.resolve('identity-obj-proxy'),
|
|
88
88
|
'^@testing-library/jest-dom$': require.resolve('@testing-library/jest-dom'),
|
|
89
89
|
'^@testing-library/react$': require.resolve('@testing-library/react'),
|
|
90
90
|
'^@testing-library/user-event$': require.resolve('@testing-library/user-event'),
|
package/config/webpack.config.js
CHANGED
|
@@ -41,7 +41,7 @@ const createEnvironmentHash = require('./createEnvironmentHash');
|
|
|
41
41
|
|
|
42
42
|
// This is the production and development configuration.
|
|
43
43
|
// It is focused on developer experience, fast rebuilds, and a minimal bundle.
|
|
44
|
-
module.exports = function (env, ilibAdditionalResourcesPath) {
|
|
44
|
+
module.exports = function (env, isomorphic = false, ilibAdditionalResourcesPath) {
|
|
45
45
|
process.chdir(app.context);
|
|
46
46
|
|
|
47
47
|
// Load applicable .env files into environment variables.
|
|
@@ -100,22 +100,18 @@ module.exports = function (env, ilibAdditionalResourcesPath) {
|
|
|
100
100
|
process.env.INLINE_STYLES ? require.resolve('style-loader') : MiniCssExtractPlugin.loader,
|
|
101
101
|
{
|
|
102
102
|
loader: require.resolve('css-loader'),
|
|
103
|
-
options: Object.assign(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
// Don't handle absolute path urls
|
|
110
|
-
if (url.startsWith('/')) {
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return true;
|
|
103
|
+
options: Object.assign({sourceMap: shouldUseSourceMap}, cssLoaderOptions, {
|
|
104
|
+
url: {
|
|
105
|
+
filter: url => {
|
|
106
|
+
// Don't handle absolute path urls
|
|
107
|
+
if (url.startsWith('/')) {
|
|
108
|
+
return false;
|
|
115
109
|
}
|
|
110
|
+
|
|
111
|
+
return true;
|
|
116
112
|
}
|
|
117
113
|
}
|
|
118
|
-
)
|
|
114
|
+
})
|
|
119
115
|
},
|
|
120
116
|
{
|
|
121
117
|
// Options for PostCSS as we reference these options twice
|
|
@@ -128,7 +124,7 @@ module.exports = function (env, ilibAdditionalResourcesPath) {
|
|
|
128
124
|
// https://github.com/facebook/create-react-app/issues/2677
|
|
129
125
|
ident: 'postcss',
|
|
130
126
|
plugins: [
|
|
131
|
-
useTailwind &&
|
|
127
|
+
useTailwind && 'tailwindcss',
|
|
132
128
|
// Fix and adjust for known flexbox issues
|
|
133
129
|
// See https://github.com/philipwalton/flexbugs
|
|
134
130
|
'postcss-flexbugs-fixes',
|
|
@@ -176,6 +172,14 @@ module.exports = function (env, ilibAdditionalResourcesPath) {
|
|
|
176
172
|
}
|
|
177
173
|
});
|
|
178
174
|
|
|
175
|
+
const getScssStyleLoaders = cssLoaderOptions =>
|
|
176
|
+
getStyleLoaders(cssLoaderOptions, {
|
|
177
|
+
loader: require.resolve('sass-loader'),
|
|
178
|
+
options: {
|
|
179
|
+
sourceMap: shouldUseSourceMap
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
179
183
|
const getAdditionalModulePaths = paths => {
|
|
180
184
|
if (!paths) return [];
|
|
181
185
|
return Array.isArray(paths) ? paths : [paths];
|
|
@@ -185,6 +189,8 @@ module.exports = function (env, ilibAdditionalResourcesPath) {
|
|
|
185
189
|
mode: isEnvProduction ? 'production' : 'development',
|
|
186
190
|
// Don't attempt to continue if there are any errors.
|
|
187
191
|
bail: true,
|
|
192
|
+
// Webpack noise constrained to errors and warnings
|
|
193
|
+
stats: 'errors-warnings',
|
|
188
194
|
// Use source maps during development builds or when specified by GENERATE_SOURCEMAP
|
|
189
195
|
devtool: shouldUseSourceMap && (isEnvProduction ? 'source-map' : 'cheap-module-source-map'),
|
|
190
196
|
// These are the "entry points" to our application.
|
|
@@ -241,6 +247,13 @@ module.exports = function (env, ilibAdditionalResourcesPath) {
|
|
|
241
247
|
infrastructureLogging: {
|
|
242
248
|
level: 'none'
|
|
243
249
|
},
|
|
250
|
+
ignoreWarnings: [
|
|
251
|
+
// We ignore 'Module not found' warnings from SnapshotPlugin
|
|
252
|
+
{
|
|
253
|
+
module: /SnapshotPlugin/,
|
|
254
|
+
message: /Module not found/
|
|
255
|
+
}
|
|
256
|
+
],
|
|
244
257
|
resolve: {
|
|
245
258
|
// These are the reasonable defaults supported by the React/ES6 ecosystem.
|
|
246
259
|
extensions: ['.js', '.mjs', '.jsx', '.ts', '.tsx', '.json'].filter(
|
|
@@ -305,9 +318,9 @@ module.exports = function (env, ilibAdditionalResourcesPath) {
|
|
|
305
318
|
{
|
|
306
319
|
test: /\.module\.css$/,
|
|
307
320
|
use: getStyleLoaders({
|
|
321
|
+
importLoaders: 1,
|
|
308
322
|
modules: {
|
|
309
|
-
getLocalIdent
|
|
310
|
-
mode: 'local'
|
|
323
|
+
getLocalIdent
|
|
311
324
|
}
|
|
312
325
|
})
|
|
313
326
|
},
|
|
@@ -316,9 +329,9 @@ module.exports = function (env, ilibAdditionalResourcesPath) {
|
|
|
316
329
|
// The `forceCSSModules` Enact build option can be set true to universally apply
|
|
317
330
|
// modular CSS support.
|
|
318
331
|
use: getStyleLoaders({
|
|
332
|
+
importLoaders: 1,
|
|
319
333
|
modules: {
|
|
320
|
-
...(app.forceCSSModules ? {getLocalIdent} : {})
|
|
321
|
-
mode: 'icss'
|
|
334
|
+
...(app.forceCSSModules ? {getLocalIdent} : {mode: 'icss'})
|
|
322
335
|
}
|
|
323
336
|
}),
|
|
324
337
|
// Don't consider CSS imports dead code even if the
|
|
@@ -330,22 +343,43 @@ module.exports = function (env, ilibAdditionalResourcesPath) {
|
|
|
330
343
|
{
|
|
331
344
|
test: /\.module\.less$/,
|
|
332
345
|
use: getLessStyleLoaders({
|
|
346
|
+
importLoaders: 2,
|
|
333
347
|
modules: {
|
|
334
|
-
getLocalIdent
|
|
335
|
-
mode: 'local'
|
|
348
|
+
getLocalIdent
|
|
336
349
|
}
|
|
337
350
|
})
|
|
338
351
|
},
|
|
339
352
|
{
|
|
340
353
|
test: /\.less$/,
|
|
341
354
|
use: getLessStyleLoaders({
|
|
355
|
+
importLoaders: 2,
|
|
342
356
|
modules: {
|
|
343
|
-
...(app.forceCSSModules ? {getLocalIdent} : {})
|
|
344
|
-
mode: 'icss'
|
|
357
|
+
...(app.forceCSSModules ? {getLocalIdent} : {mode: 'icss'})
|
|
345
358
|
}
|
|
346
359
|
}),
|
|
347
360
|
sideEffects: true
|
|
348
361
|
},
|
|
362
|
+
// Opt-in support for CSS Modules, but using SASS
|
|
363
|
+
// using the extension .module.scss or .module.sass
|
|
364
|
+
{
|
|
365
|
+
test: /\.module\.(scss|sass)$/,
|
|
366
|
+
use: getScssStyleLoaders({
|
|
367
|
+
importLoaders: 3,
|
|
368
|
+
modules: {
|
|
369
|
+
getLocalIdent
|
|
370
|
+
}
|
|
371
|
+
})
|
|
372
|
+
},
|
|
373
|
+
// Opt-in support for SASS (using .scss or .sass extensions)
|
|
374
|
+
{
|
|
375
|
+
test: /\.(scss|sass)$/,
|
|
376
|
+
use: getScssStyleLoaders({
|
|
377
|
+
importLoaders: 3,
|
|
378
|
+
modules: {
|
|
379
|
+
...(app.forceCSSModules ? {getLocalIdent} : {mode: 'icss'})
|
|
380
|
+
}
|
|
381
|
+
})
|
|
382
|
+
},
|
|
349
383
|
// "file" loader handles on all files not caught by the above loaders.
|
|
350
384
|
// When you `import` an asset, you get its output filename and the file
|
|
351
385
|
// is copied during the build process.
|
|
@@ -365,12 +399,6 @@ module.exports = function (env, ilibAdditionalResourcesPath) {
|
|
|
365
399
|
}
|
|
366
400
|
].filter(Boolean)
|
|
367
401
|
},
|
|
368
|
-
// Specific webpack-dev-server options.
|
|
369
|
-
devServer: {
|
|
370
|
-
// Broadcast http server on the localhost, port 8080.
|
|
371
|
-
host: '0.0.0.0',
|
|
372
|
-
port: 8080
|
|
373
|
-
},
|
|
374
402
|
// Target app to build for a specific environment (default 'browserslist')
|
|
375
403
|
target: app.environment,
|
|
376
404
|
// Optional configuration for polyfilling NodeJS built-ins.
|
|
@@ -450,7 +478,10 @@ module.exports = function (env, ilibAdditionalResourcesPath) {
|
|
|
450
478
|
// Otherwise React will be compiled in the very slow development mode.
|
|
451
479
|
new DefinePlugin({
|
|
452
480
|
'process.env.NODE_ENV': JSON.stringify(isEnvProduction ? 'production' : 'development'),
|
|
453
|
-
'process.env.PUBLIC_URL': JSON.stringify(publicPath)
|
|
481
|
+
'process.env.PUBLIC_URL': JSON.stringify(publicPath),
|
|
482
|
+
// Define ENACT_PACK_ISOMORPHIC global variable to determine to use
|
|
483
|
+
// `hydrateRoot` for isomorphic build and `createRoot` for non-isomorphic build by app.
|
|
484
|
+
ENACT_PACK_ISOMORPHIC: isomorphic
|
|
454
485
|
}),
|
|
455
486
|
// Inject prefixed environment variables within code, when used
|
|
456
487
|
new EnvironmentPlugin(Object.keys(process.env).filter(key => /^(REACT_APP|WDS_SOCKET)/.test(key))),
|
package/docs/building-apps.md
CHANGED
|
@@ -104,6 +104,98 @@ npm install --save typescript @types/react @types/react-dom @types/jest
|
|
|
104
104
|
|
|
105
105
|
Optionally, [ESLint](https://eslint.org) can be installed globally or locally and configured within a project to enable linting support within the `enact lint` command.
|
|
106
106
|
|
|
107
|
+
## Sass Support
|
|
108
|
+
|
|
109
|
+
CSS stylesheets could get larger and more complex as you develop. To help and enrich the styling of your apps, there are great CSS preprocessors
|
|
110
|
+
out there. Enact CLI provides [LESS](https://lesscss.org) as the default and [Sass](https://sass-lang.com) support is an optional feature since Enact CLI 5.0.0.
|
|
111
|
+
|
|
112
|
+
To use Sass, install Sass globally:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npm install -g sass
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Now you can rename `src/App.css` to `src/App.scss` or `src/App.sass` and for using CSS modules, `src/App.module.scss` or `src/App.module.sass`. And update `src/App.js` to import `src/App.scss`. Enact CLI will compile these files properly through webpack for you.
|
|
119
|
+
|
|
120
|
+
More information can be found [here](https://sass-lang.com/guide) to learn about Sass.
|
|
121
|
+
|
|
122
|
+
## Tailwind CSS Support
|
|
123
|
+
|
|
124
|
+
Tailwind CSS works by scanning all of your HTML files, JavaScript components, and any other templates for class names, generating the corresponding styles and then writing them to a static CSS file.
|
|
125
|
+
Enact CLI supports to use Tailwind CSS as an optional feature since Enact CLI 5.0.0.
|
|
126
|
+
|
|
127
|
+
To use Tailwindcss, install Tailwindcss globally:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npm install -g tailwindcss
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
And then run the init command to generate tailwind.config.js in your app:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npx tailwindcss init
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Add the paths to all of your template files in your tailwind.config.js file.
|
|
140
|
+
|
|
141
|
+
```js
|
|
142
|
+
module.exports = {
|
|
143
|
+
content: [
|
|
144
|
+
"./src/**/*.{js,jsx,ts,tsx}",
|
|
145
|
+
],
|
|
146
|
+
theme: {
|
|
147
|
+
extend: {},
|
|
148
|
+
},
|
|
149
|
+
plugins: [],
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Create `src/tailwind.css` file and add the @tailwind directives for each of Tailwind’s layers to your file.
|
|
154
|
+
|
|
155
|
+
```css
|
|
156
|
+
@tailwind base;
|
|
157
|
+
@tailwind components;
|
|
158
|
+
@tailwind utilities;
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Import `src/tailwind.css` into your `src/index.js` file.
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
import {createRoot} from 'react-dom/client';
|
|
165
|
+
import App from './App';
|
|
166
|
+
import './tailwind.css';
|
|
167
|
+
|
|
168
|
+
const appElement = (<App />);
|
|
169
|
+
...
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Now you can start using Tailwind’s utility classes to style your content.
|
|
173
|
+
Here is the example.
|
|
174
|
+
|
|
175
|
+
```js
|
|
176
|
+
const MainPanel = kind({
|
|
177
|
+
name: 'MainPanel',
|
|
178
|
+
|
|
179
|
+
render: (props) => (
|
|
180
|
+
<Panel {...props}>
|
|
181
|
+
<p className="text-3xl font-bold underline">
|
|
182
|
+
Edit src/views/MainPanel.js and save to reload.
|
|
183
|
+
</p>
|
|
184
|
+
</Panel>
|
|
185
|
+
)
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
More information can be found [here](https://tailwindcss.com/docs) to learn about tailwindcss.
|
|
190
|
+
|
|
191
|
+
### Troubleshooting
|
|
192
|
+
If you receive an error when building the app that says `Cannot find module: 'typescript/sass/tailwindcss'` after installing the modules above(e.g. `typescript`, `sass`, or `tailwindcss`) globally,
|
|
193
|
+
try to set `NODE_PATH` to point global node_modules directory like below.
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
export NODE_PATH=/path/to/your/global/node_modules
|
|
197
|
+
```
|
|
198
|
+
|
|
107
199
|
## Isomorphic Support & Prerendering
|
|
108
200
|
By using the isomorphic code layout option, your project bundle will be outputted in a versatile universal code format allowing potential usage outside the browser. The Enact CLI takes advantage of this mode by additionally generating an HTML output of your project and embedding it directly with the resulting **index.html**. By default, isomorphic mode will attempt to prerender only `en-US`, however with the `--locales` option, a wide variety of locales can be specified and prerendered. More details on isomorphic support and its limitations can be found [here](./isomorphic-support.md).
|
|
109
201
|
|
|
@@ -31,6 +31,32 @@ npm pack -- --isomorphic
|
|
|
31
31
|
npm pack-p -- --isomorphic
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
If you are using React18, you need to call `hydrateRoot` instead of `createRoot` to hydrate prerendered HTML.
|
|
35
|
+
Enact CLI provides a global variable `ENACT_PACK_ISOMORPHIC` to selectively call those two APIs in your app's `index.js`.
|
|
36
|
+
If you build with isomorphic option, `ENACT_PACK_ISOMORPHIC` will be `true`, otherwise `false`.
|
|
37
|
+
For more detailed information, please refer to the [React 18 migration guide](https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#updates-to-client-rendering-apis).
|
|
38
|
+
|
|
39
|
+
Whithin your **src/index.js** file, add a conditional statement to render or hydrate your app:
|
|
40
|
+
```js
|
|
41
|
+
/* global ENACT_PACK_ISOMORPHIC */
|
|
42
|
+
import {createRoot, hydrateRoot} from 'react-dom/client';
|
|
43
|
+
|
|
44
|
+
import App from './App';
|
|
45
|
+
|
|
46
|
+
const appElement = (<App />);
|
|
47
|
+
|
|
48
|
+
// In a browser environment, render the app to the document.
|
|
49
|
+
if (typeof window !== 'undefined') {
|
|
50
|
+
if (ENACT_PACK_ISOMORPHIC) {
|
|
51
|
+
hydrateRoot(document.getElementById('root'), appElement);
|
|
52
|
+
} else {
|
|
53
|
+
createRoot(document.getElementById('root')).render(appElement);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default appElement;
|
|
58
|
+
```
|
|
59
|
+
|
|
34
60
|
### When to Build Isomorphically
|
|
35
61
|
By default, the Enact CLI will not use isomorphic code layout, and it should not be considered part of the regular development workflow. It is advisable to only build in isomorphic format when you want to test isomorphic features or in production mode builds.
|
|
36
62
|
|