b13-rocket 0.5.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/.editorconfig +102 -0
- package/.gitlab-ci.yml +14 -0
- package/.nvmrc +1 -0
- package/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs +541 -0
- package/.yarn/releases/yarn-3.2.3.cjs +783 -0
- package/.yarnrc.yml +5 -0
- package/README.md +98 -0
- package/eslintrc.json +207 -0
- package/files/.ddev/commands/web/rocket.sh +10 -0
- package/files/.ddev/docker-compose.webpack.yaml +9 -0
- package/index.js +4 -0
- package/package.json +71 -0
- package/src/build.js +158 -0
- package/src/cli.js +57 -0
- package/src/create.js +65 -0
- package/src/help.js +36 -0
- package/src/hmr.js +84 -0
- package/src/notification.js +55 -0
- package/src/scss/lessBuild.js +104 -0
- package/src/scss/scssBuild.js +186 -0
- package/src/sites.js +53 -0
- package/src/stylelint.js +33 -0
- package/src/utility/env.js +49 -0
- package/src/version.js +6 -0
- package/src/webpack/webpack.config.base.js +113 -0
- package/src/webpack/webpack.config.js +83 -0
package/.yarnrc.yml
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Rocket FE build setup
|
|
2
|
+
|
|
3
|
+
## Requirements
|
|
4
|
+
|
|
5
|
+
* node = 16.13.0 (https://nodejs.org/en/download/)
|
|
6
|
+
* npm = 6.4.1 (https://www.npmjs.com/get-npm)
|
|
7
|
+
* yarn = 1.12.3 (https://yarnpkg.com/en/docs/install)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## Init
|
|
11
|
+
|
|
12
|
+
`yarn install`
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## Build JS and CSS
|
|
16
|
+
|
|
17
|
+
`yarn rocket build`
|
|
18
|
+
|
|
19
|
+
## CLI Options
|
|
20
|
+
|
|
21
|
+
`yarn rocket help`
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Caches
|
|
26
|
+
|
|
27
|
+
`webpack` and `babel-loader` build caches are stored in `node_modules/.cache/`
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## TYPO3 Setup
|
|
32
|
+
|
|
33
|
+
Site Extension JS include setup:
|
|
34
|
+
|
|
35
|
+
### constants.typoscript
|
|
36
|
+
```
|
|
37
|
+
# enable hot module replacement (hmr)
|
|
38
|
+
enableHMR = 0
|
|
39
|
+
enableHMR := getEnv(TYPO3_TS_ENABLE_HMR)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### setup.typoscript
|
|
43
|
+
```
|
|
44
|
+
page.includeJSFooter {
|
|
45
|
+
vendor = EXT:YOUR_EXT_NAME/Resources/Public/JavaScript/common-vendor.js
|
|
46
|
+
vendor.if.isFalse = {$enableHMR}
|
|
47
|
+
vendor.type = module
|
|
48
|
+
main = EXT:YOUR_EXT_NAME/Resources/Public/JavaScript/main.js
|
|
49
|
+
main.if.isFalse = {$enableHMR}
|
|
50
|
+
main.type = module
|
|
51
|
+
|
|
52
|
+
# if hot module replacement is enabled
|
|
53
|
+
vendor-hmr = https://DOMAIN:8088/typo3conf/ext/YOUR_EXT_NAME/Resources/Public/JavaScript/common-vendor-hmr.js
|
|
54
|
+
vendor-hmr.if.isTrue = {$enableHMR}
|
|
55
|
+
main-hmr = https://DOMAIN:8088/typo3conf/ext/YOUR_EXT_NAME/Resources/Public/JavaScript/main-hmr.js
|
|
56
|
+
main-hmr.if.isTrue = {$enableHMR}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Update to Yarn v3
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
// switch to latest yarn version
|
|
66
|
+
yarn set version berry
|
|
67
|
+
|
|
68
|
+
// update node dependencies
|
|
69
|
+
yarn install
|
|
70
|
+
yarn remove b13-build-cli
|
|
71
|
+
yarn add "b13-build-cli@ssh://git@code.b13.com/infrastructure/rocket-cli.git#^0.3.0"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Update .gitignore
|
|
75
|
+
```
|
|
76
|
+
.pnp.*
|
|
77
|
+
.yarn/*
|
|
78
|
+
!.yarn/patches
|
|
79
|
+
!.yarn/plugins
|
|
80
|
+
!.yarn/releases
|
|
81
|
+
!.yarn/sdks
|
|
82
|
+
!.yarn/versions
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Update package.json script call: (use 'yarn node' instead of 'node')
|
|
86
|
+
```
|
|
87
|
+
....
|
|
88
|
+
"scripts": {
|
|
89
|
+
"rocket": "yarn node ./node_modules/b13-build-cli/index.js",
|
|
90
|
+
}
|
|
91
|
+
...
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Use hmr inside ddev container
|
|
95
|
+
|
|
96
|
+
1. Copy files from `files` directory to your `.ddev` directory.
|
|
97
|
+
2. Restart ddev (`ddev restart`)
|
|
98
|
+
3. Start rocket via ddev command: `ddev rocket`, `ddev rocket hmr --site=....` etc.
|
package/eslintrc.json
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
{
|
|
2
|
+
"parserOptions": {
|
|
3
|
+
"ecmaVersion": "latest",
|
|
4
|
+
"sourceType": "module"
|
|
5
|
+
},
|
|
6
|
+
"extends": [
|
|
7
|
+
"eslint:recommended"
|
|
8
|
+
],
|
|
9
|
+
"globals": {
|
|
10
|
+
"B13_HMR_ENABLED": "readable"
|
|
11
|
+
},
|
|
12
|
+
"rules": {
|
|
13
|
+
"array-bracket-spacing": ["error", "never"],
|
|
14
|
+
"array-callback-return": "error",
|
|
15
|
+
"arrow-body-style": ["error", "as-needed"],
|
|
16
|
+
"arrow-spacing": "error",
|
|
17
|
+
"indent": ["warn", "tab", { "SwitchCase": 1 }],
|
|
18
|
+
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
|
|
19
|
+
"camelcase": "error",
|
|
20
|
+
"callback-return": ["error", ["cb", "callback", "next"]],
|
|
21
|
+
"class-methods-use-this": "error",
|
|
22
|
+
"comma-dangle": ["error", "always-multiline"],
|
|
23
|
+
"comma-spacing": "error",
|
|
24
|
+
"comma-style": ["error", "last"],
|
|
25
|
+
"computed-property-spacing": "error",
|
|
26
|
+
"consistent-return": "warn",
|
|
27
|
+
"curly": ["error", "all"],
|
|
28
|
+
"default-case": "warn",
|
|
29
|
+
"dot-location": ["error", "property"],
|
|
30
|
+
"dot-notation": ["error", { "allowKeywords": true }],
|
|
31
|
+
"eol-last": "error",
|
|
32
|
+
"eqeqeq": "error",
|
|
33
|
+
"func-call-spacing": ["warn", "never"],
|
|
34
|
+
"func-style": ["error", "declaration"],
|
|
35
|
+
"function-paren-newline": ["error", "consistent"],
|
|
36
|
+
"generator-star-spacing": "error",
|
|
37
|
+
"guard-for-in": "error",
|
|
38
|
+
"handle-callback-err": ["error", "err"],
|
|
39
|
+
"key-spacing": ["error", { "mode": "strict" }],
|
|
40
|
+
"keyword-spacing": "error",
|
|
41
|
+
"lines-around-comment": ["error", {
|
|
42
|
+
"beforeBlockComment": true,
|
|
43
|
+
"afterBlockComment": false,
|
|
44
|
+
"beforeLineComment": true,
|
|
45
|
+
"afterLineComment": false
|
|
46
|
+
}],
|
|
47
|
+
"max-len": ["error", 160, {
|
|
48
|
+
"ignoreComments": true,
|
|
49
|
+
"ignoreUrls": true,
|
|
50
|
+
"ignoreStrings": true,
|
|
51
|
+
"ignoreTemplateLiterals": true,
|
|
52
|
+
"ignoreRegExpLiterals": true
|
|
53
|
+
}],
|
|
54
|
+
|
|
55
|
+
"max-statements-per-line": "error",
|
|
56
|
+
"new-cap": "error",
|
|
57
|
+
"new-parens": "error",
|
|
58
|
+
"no-alert": "error",
|
|
59
|
+
"no-array-constructor": "error",
|
|
60
|
+
"no-buffer-constructor": "error",
|
|
61
|
+
"no-caller": "error",
|
|
62
|
+
"no-confusing-arrow": "error",
|
|
63
|
+
"no-console": ["warn", { "allow": ["warn", "error", "log"] }],
|
|
64
|
+
"no-delete-var": "error",
|
|
65
|
+
"no-else-return": "error",
|
|
66
|
+
"no-eval": "error",
|
|
67
|
+
"no-extend-native": "error",
|
|
68
|
+
"no-extra-bind": "error",
|
|
69
|
+
"no-fallthrough": "error",
|
|
70
|
+
"no-floating-decimal": "error",
|
|
71
|
+
"no-global-assign": "error",
|
|
72
|
+
"no-implied-eval": "error",
|
|
73
|
+
"no-invalid-this": "off",
|
|
74
|
+
"no-iterator": "error",
|
|
75
|
+
"no-label-var": "error",
|
|
76
|
+
"no-labels": "error",
|
|
77
|
+
"no-lone-blocks": "error",
|
|
78
|
+
"no-loop-func": "error",
|
|
79
|
+
"no-mixed-spaces-and-tabs": ["warn", false],
|
|
80
|
+
"no-multi-spaces": "error",
|
|
81
|
+
"no-multi-str": "error",
|
|
82
|
+
"no-multiple-empty-lines": ["error", {"max": 2, "maxBOF": 0, "maxEOF": 0}],
|
|
83
|
+
"no-nested-ternary": "error",
|
|
84
|
+
"no-octal": "error",
|
|
85
|
+
"no-octal-escape": "error",
|
|
86
|
+
"no-param-reassign": "error",
|
|
87
|
+
"no-path-concat": "error",
|
|
88
|
+
"no-process-exit": "error",
|
|
89
|
+
"no-proto": "error",
|
|
90
|
+
"no-redeclare": "error",
|
|
91
|
+
"no-restricted-properties": [
|
|
92
|
+
"error",
|
|
93
|
+
{
|
|
94
|
+
"property": "substring",
|
|
95
|
+
"message": "Use .slice instead of .substring."
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"property": "substr",
|
|
99
|
+
"message": "Use .slice instead of .substr."
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"object": "assert",
|
|
103
|
+
"property": "equal",
|
|
104
|
+
"message": "Use assert.strictEqual instead of assert.equal."
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"object": "assert",
|
|
108
|
+
"property": "notEqual",
|
|
109
|
+
"message": "Use assert.notStrictEqual instead of assert.notEqual."
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"object": "assert",
|
|
113
|
+
"property": "deepEqual",
|
|
114
|
+
"message": "Use assert.deepStrictEqual instead of assert.deepEqual."
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"object": "assert",
|
|
118
|
+
"property": "notDeepEqual",
|
|
119
|
+
"message": "Use assert.notDeepStrictEqual instead of assert.notDeepEqual."
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
"no-return-assign": "error",
|
|
123
|
+
"no-script-url": "error",
|
|
124
|
+
"no-self-assign": "error",
|
|
125
|
+
"no-self-compare": "error",
|
|
126
|
+
"no-sequences": "error",
|
|
127
|
+
"no-shadow": ["off", { "builtinGlobals": true, "hoist": "never", "allow": [] }],
|
|
128
|
+
"no-throw-literal": "error",
|
|
129
|
+
"no-trailing-spaces": "warn",
|
|
130
|
+
"no-undef": ["error", {"typeof": true}],
|
|
131
|
+
"no-undef-init": "error",
|
|
132
|
+
"no-undefined": "error",
|
|
133
|
+
"no-underscore-dangle": ["error", {"allowAfterThis": true}],
|
|
134
|
+
"no-unmodified-loop-condition": "error",
|
|
135
|
+
"no-unneeded-ternary": "error",
|
|
136
|
+
"no-unused-expressions": "error",
|
|
137
|
+
"no-unused-vars": ["error", {"vars": "all", "args": "after-used"}],
|
|
138
|
+
"no-use-before-define": "off",
|
|
139
|
+
"no-useless-call": "error",
|
|
140
|
+
"no-useless-computed-key": "error",
|
|
141
|
+
"no-useless-concat": "error",
|
|
142
|
+
"no-useless-constructor": "error",
|
|
143
|
+
"no-useless-escape": "error",
|
|
144
|
+
"no-useless-rename": "error",
|
|
145
|
+
"no-useless-return": "error",
|
|
146
|
+
"no-whitespace-before-property": "error",
|
|
147
|
+
"no-var": "error",
|
|
148
|
+
"object-curly-newline": ["error", { "consistent": true, "multiline": true }],
|
|
149
|
+
"object-curly-spacing": ["error", "always"],
|
|
150
|
+
"object-property-newline": ["error",
|
|
151
|
+
{
|
|
152
|
+
"allowAllPropertiesOnSameLine": true
|
|
153
|
+
}
|
|
154
|
+
],
|
|
155
|
+
"object-shorthand": "error",
|
|
156
|
+
"one-var-declaration-per-line": "error",
|
|
157
|
+
"operator-assignment": "error",
|
|
158
|
+
"operator-linebreak": ["error", "after"],
|
|
159
|
+
"padding-line-between-statements": [
|
|
160
|
+
"off",
|
|
161
|
+
{
|
|
162
|
+
"blankLine": "always",
|
|
163
|
+
"prev": ["const", "let", "var"],
|
|
164
|
+
"next": "*"
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"blankLine": "any",
|
|
168
|
+
"prev": ["const", "let", "var"],
|
|
169
|
+
"next": ["const", "let", "var"]
|
|
170
|
+
}
|
|
171
|
+
],
|
|
172
|
+
"prefer-arrow-callback": "warn",
|
|
173
|
+
"prefer-const": "warn",
|
|
174
|
+
"prefer-numeric-literals": "error",
|
|
175
|
+
"prefer-promise-reject-errors": "error",
|
|
176
|
+
"prefer-rest-params": "error",
|
|
177
|
+
"prefer-spread": "error",
|
|
178
|
+
"prefer-template": "warn",
|
|
179
|
+
"quotes": ["error", "single"],
|
|
180
|
+
"quote-props": ["error", "as-needed"],
|
|
181
|
+
"radix": "error",
|
|
182
|
+
"rest-spread-spacing": "error",
|
|
183
|
+
"semi": ["error", "always"],
|
|
184
|
+
"semi-spacing": ["error", {"before": false, "after": true}],
|
|
185
|
+
"semi-style": "error",
|
|
186
|
+
"space-before-blocks": "error",
|
|
187
|
+
"space-before-function-paren": ["error", "never"],
|
|
188
|
+
"space-in-parens": "error",
|
|
189
|
+
"space-infix-ops": "error",
|
|
190
|
+
"space-unary-ops": ["error", {"words": true, "nonwords": false}],
|
|
191
|
+
"spaced-comment": ["error", "always", { "exceptions": ["-"]}],
|
|
192
|
+
"strict": ["error", "global"],
|
|
193
|
+
"switch-colon-spacing": "error",
|
|
194
|
+
"symbol-description": "error",
|
|
195
|
+
"template-curly-spacing": ["error", "never"],
|
|
196
|
+
"template-tag-spacing": "error",
|
|
197
|
+
"unicode-bom": "error",
|
|
198
|
+
"wrap-iife": ["error", "any"],
|
|
199
|
+
"yield-star-spacing": "error",
|
|
200
|
+
"yoda": ["error", "never"]
|
|
201
|
+
},
|
|
202
|
+
"env": {
|
|
203
|
+
"amd": true,
|
|
204
|
+
"es2021": true,
|
|
205
|
+
"node": true
|
|
206
|
+
}
|
|
207
|
+
}
|
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "b13-rocket",
|
|
3
|
+
"description": "FE CLI build tool",
|
|
4
|
+
"version": "0.5.0",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=v16.13.0",
|
|
7
|
+
"npm": ">=6.4.1",
|
|
8
|
+
"yarn": "^1.12.3"
|
|
9
|
+
},
|
|
10
|
+
"author": {
|
|
11
|
+
"name": "b13 GmbH",
|
|
12
|
+
"email": "info@b13.com",
|
|
13
|
+
"url": "https://b13.com/"
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"rocket": "node ./index.js"
|
|
17
|
+
},
|
|
18
|
+
"main": "index.js",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@babel/core": "7",
|
|
21
|
+
"@babel/plugin-transform-runtime": "7",
|
|
22
|
+
"@babel/preset-env": "7",
|
|
23
|
+
"@babel/preset-typescript": "7",
|
|
24
|
+
"@babel/runtime": "7",
|
|
25
|
+
"autoprefixer": "^10.4.13",
|
|
26
|
+
"b13-eslint-config": "https://code.b13.com/public-projects/es-lint-config.git",
|
|
27
|
+
"b13-stylelint-config": "https://code.b13.com/public-projects/stylelint-config.git#0.1.0",
|
|
28
|
+
"babel-loader": "^8.2.5",
|
|
29
|
+
"chalk": "^4.1.2",
|
|
30
|
+
"child_process": "^1.0.2",
|
|
31
|
+
"compression-webpack-plugin": "^7.1.2",
|
|
32
|
+
"css-loader": "^5.2.7",
|
|
33
|
+
"cssnano": "^5.1.14",
|
|
34
|
+
"eslint": "^8",
|
|
35
|
+
"eslint-plugin-vue": "^9.9.0",
|
|
36
|
+
"esm": "^3.2.25",
|
|
37
|
+
"expose-loader": "^2.0.0",
|
|
38
|
+
"file-loader": "^6.2.0",
|
|
39
|
+
"filesize": "^6.4.0",
|
|
40
|
+
"html-loader": "^2.1.2",
|
|
41
|
+
"less": "^4.1.3",
|
|
42
|
+
"path": "^0.12.7",
|
|
43
|
+
"postcss": "^8.4.16",
|
|
44
|
+
"postcss-sort-media-queries": "^4.3.0",
|
|
45
|
+
"readline": "^1.3.0",
|
|
46
|
+
"sass": "^1.56.1",
|
|
47
|
+
"sass-loader": "^11.1.1",
|
|
48
|
+
"stylelint": "^14.16.1",
|
|
49
|
+
"vue": "^2.7.0",
|
|
50
|
+
"vue-loader": "^15.10.1",
|
|
51
|
+
"vue-svg-inline-loader": "^2.1.5",
|
|
52
|
+
"vue-template-compiler": "^2.7.10",
|
|
53
|
+
"webpack": "^5.75.0",
|
|
54
|
+
"webpack-cli": "^5.0.0",
|
|
55
|
+
"webpack-dev-server": "^4.11.1",
|
|
56
|
+
"webpack-merge": "^5.8.0",
|
|
57
|
+
"workbox-webpack-plugin": "^6.5.4"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"webpack-bundle-analyzer": "^4.7.0"
|
|
61
|
+
},
|
|
62
|
+
"packageManager": "yarn@3.2.3",
|
|
63
|
+
"dependenciesMeta": {
|
|
64
|
+
"b13-eslint-config@0.2.3": {
|
|
65
|
+
"unplugged": true
|
|
66
|
+
},
|
|
67
|
+
"eslint@8.34.0": {
|
|
68
|
+
"unplugged": true
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
package/src/build.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { sites } from './sites';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { ScssBuild } from './scss/scssBuild';
|
|
5
|
+
import { LessBuild } from './scss/lessBuild';
|
|
6
|
+
import webpack from 'webpack';
|
|
7
|
+
import { default as webpackConfig } from './webpack/webpack.config';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import { Notification } from './notification';
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Build {
|
|
13
|
+
constructor(config = {}, sitesConfigPath = '', mode = 'production') {
|
|
14
|
+
this.sitesConfigPath = sitesConfigPath;
|
|
15
|
+
this.config = config;
|
|
16
|
+
this.mode = mode;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// make sure JS public directory exists and is clean
|
|
20
|
+
clear() {
|
|
21
|
+
const jsPath = path.resolve(this.sitesConfigPath, this.config.js.path.target);
|
|
22
|
+
if (!fs.existsSync(jsPath)) {
|
|
23
|
+
fs.mkdirSync(jsPath);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
fs.readdirSync(jsPath, { withFileTypes: true }).forEach((file) => {
|
|
27
|
+
|
|
28
|
+
// only remove file
|
|
29
|
+
// skip directories
|
|
30
|
+
if (file.isFile()) {
|
|
31
|
+
fs.unlinkSync(path.resolve(this.sitesConfigPath, `${this.config.js.path.target}/${file.name}`), (err) => {
|
|
32
|
+
if (err) {
|
|
33
|
+
throw err;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
build() {
|
|
41
|
+
const wpConfig = webpackConfig(this.config, this.sitesConfigPath, this.mode);
|
|
42
|
+
const compiler = webpack(wpConfig);
|
|
43
|
+
|
|
44
|
+
compiler.hooks.beforeRun.tap('b13-rocket-cli', (context, entry) => {
|
|
45
|
+
this.clear();
|
|
46
|
+
if (this.config.sw) {
|
|
47
|
+
this.updateServiceWorkerBuildTimestamp();
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
compiler.run((err, stats) => {
|
|
52
|
+
|
|
53
|
+
Notification.taskInfo('Process JavaScript file(s)');
|
|
54
|
+
|
|
55
|
+
if (err) {
|
|
56
|
+
Notification.error('JS build failed', err.stack || err);
|
|
57
|
+
if (err.details) {
|
|
58
|
+
Notification.error('JS build failed', err.details);
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (stats.hasErrors()) {
|
|
64
|
+
Notification.error('JS build failed', stats.toString({
|
|
65
|
+
chunks: false,
|
|
66
|
+
colors: true,
|
|
67
|
+
}));
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const info = stats.toJson();
|
|
72
|
+
if (stats.hasWarnings()) {
|
|
73
|
+
Notification.warn(info.warnings);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
Notification.log(stats.toString({
|
|
77
|
+
chunks: false,
|
|
78
|
+
colors: true,
|
|
79
|
+
}));
|
|
80
|
+
|
|
81
|
+
compiler.close((closeErr) => {
|
|
82
|
+
|
|
83
|
+
// ...
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// update service worker build timestamp to purge service worker cache
|
|
89
|
+
updateServiceWorkerBuildTimestamp() {
|
|
90
|
+
fs.readFile(
|
|
91
|
+
path.resolve(this.sitesConfigPath, `${this.config.sw.path.source}/${this.config.sw.filename.main}.js`),
|
|
92
|
+
'utf8',
|
|
93
|
+
(err, data) => {
|
|
94
|
+
if (err) {throw err;}
|
|
95
|
+
const timestamp = (Date.now() / 1000 | 0).toString();
|
|
96
|
+
const result = data.replace(/const\sbuildTimestamp\s=\s\'\d{0,10}\'\;/g, `const buildTimestamp = '${timestamp}';`);
|
|
97
|
+
fs.writeFile(
|
|
98
|
+
path.resolve(this.sitesConfigPath, `${this.config.sw.path.source}/${this.config.sw.filename.main}.js`),
|
|
99
|
+
result,
|
|
100
|
+
'utf8',
|
|
101
|
+
(err) => {
|
|
102
|
+
if (err) {throw err;}
|
|
103
|
+
console.log('Updated service worker build timestamp');
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
},
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
export async function build(args) {
|
|
113
|
+
const { siteConfig } = await sites(args);
|
|
114
|
+
|
|
115
|
+
if (!args.sitesConfigPath) {
|
|
116
|
+
Notification.error('missing site build config');
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const sitesConfigPath = args.sitesConfigPath;
|
|
121
|
+
const mode = args.mode ? args.mode : 'production';
|
|
122
|
+
const target = args.target ? args.target : 'all';
|
|
123
|
+
|
|
124
|
+
for (const [key, site] of siteConfig) {
|
|
125
|
+
if (args.site && key !== args.site) {
|
|
126
|
+
|
|
127
|
+
// skip other sites
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (args.bundleAnalyzer) {
|
|
132
|
+
site.config.bundleAnalyzer = true;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (site.hasScss() && ['all', 'scss'].includes(target)) {
|
|
136
|
+
const scss = new ScssBuild(site.config, sitesConfigPath);
|
|
137
|
+
scss.clear();
|
|
138
|
+
scss.build();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (site.hasLess() && ['all', 'less'].includes(target)) {
|
|
142
|
+
const less = new LessBuild(site.config, sitesConfigPath);
|
|
143
|
+
less.clear();
|
|
144
|
+
less.build();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (site.hasJs() && ['all', 'js'].includes(target)) {
|
|
148
|
+
const wpBuild = new Build(site.config, sitesConfigPath, mode);
|
|
149
|
+
wpBuild.build();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (args.site && key === args.site) {
|
|
153
|
+
|
|
154
|
+
// required site build is done
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import minimist from 'minimist';
|
|
2
|
+
import { help } from './help';
|
|
3
|
+
import { build } from './build';
|
|
4
|
+
import { hmr } from './hmr';
|
|
5
|
+
import { version } from './version';
|
|
6
|
+
import { stylelint } from './stylelint';
|
|
7
|
+
import { create } from './create';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
|
|
10
|
+
export async function cli(argsArray) {
|
|
11
|
+
const args = minimist(argsArray.slice(2));
|
|
12
|
+
let cmd = args._[0] || 'help';
|
|
13
|
+
|
|
14
|
+
// add default site config path
|
|
15
|
+
if (!args.sitesConfigPath) {
|
|
16
|
+
args.sitesConfigPath = './config';
|
|
17
|
+
}
|
|
18
|
+
args.sitesConfigPath = path.resolve(process.env.INIT_CWD, args.sitesConfigPath);
|
|
19
|
+
|
|
20
|
+
if (args.version || args.v) {
|
|
21
|
+
cmd = 'version';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (args.help || args.h) {
|
|
25
|
+
cmd = 'help';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
switch (cmd) {
|
|
29
|
+
case 'version':
|
|
30
|
+
version(args);
|
|
31
|
+
break;
|
|
32
|
+
|
|
33
|
+
case 'help':
|
|
34
|
+
help(args);
|
|
35
|
+
break;
|
|
36
|
+
|
|
37
|
+
case 'build':
|
|
38
|
+
build(args);
|
|
39
|
+
break;
|
|
40
|
+
|
|
41
|
+
case 'hmr':
|
|
42
|
+
hmr(args);
|
|
43
|
+
break;
|
|
44
|
+
|
|
45
|
+
case 'stylelint':
|
|
46
|
+
stylelint(args);
|
|
47
|
+
break;
|
|
48
|
+
|
|
49
|
+
case 'create':
|
|
50
|
+
create(args);
|
|
51
|
+
break;
|
|
52
|
+
|
|
53
|
+
default:
|
|
54
|
+
console.error(`"${cmd}" is not a valid command!`);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
package/src/create.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import { Notification } from './notification';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import readline from 'readline';
|
|
5
|
+
|
|
6
|
+
// config file
|
|
7
|
+
const CONFIG_TEMPLATE = (CONFIG_EXT_NAME = '', CONFIG_PKG_NAME = '') => `const relExtPath = '../../../web/typo3conf/ext/${CONFIG_EXT_NAME}';
|
|
8
|
+
const relScssPath = \`\${relExtPath}/Resources/Private/Scss\`;
|
|
9
|
+
const relCssPath = \`\${relExtPath}/Resources/Public/Css\`;
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
name: '${CONFIG_PKG_NAME}',
|
|
13
|
+
scss: {
|
|
14
|
+
path: {
|
|
15
|
+
source: relScssPath,
|
|
16
|
+
target: relCssPath
|
|
17
|
+
},
|
|
18
|
+
// target (CSS) : source (SCSS)
|
|
19
|
+
files: {
|
|
20
|
+
[\`\${relCssPath}/main.css\`]: \`\${relScssPath}/main.scss\`
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
js: {
|
|
24
|
+
path: {
|
|
25
|
+
source: \`\${relExtPath}/Resources/Private/JavaScript\`,
|
|
26
|
+
target: \`\${relExtPath}/Resources/Public/JavaScript\`,
|
|
27
|
+
public: '/typo3conf/ext/YOUR_EXT_NAME/Resources/Public/JavaScript/'
|
|
28
|
+
},
|
|
29
|
+
filename: {
|
|
30
|
+
main : 'main',
|
|
31
|
+
commonVendor: 'common-vendor'
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
class Create {
|
|
38
|
+
static createConfigFile(sitesConfigPath = './', fileName = 'demo.package.js', extName = '', pkgName = '') {
|
|
39
|
+
const newConfigFile = path.resolve(sitesConfigPath, fileName);
|
|
40
|
+
fs.writeFile(newConfigFile, CONFIG_TEMPLATE(extName, pkgName), (error) => {
|
|
41
|
+
if (error) {
|
|
42
|
+
Notification.error(`Can't write file: ${newConfigFile} error: ${error}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
Notification.success(` new ${newConfigFile} config created`);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function create(args) {
|
|
51
|
+
|
|
52
|
+
const rl = readline.createInterface({
|
|
53
|
+
input: process.stdin,
|
|
54
|
+
output: process.stdout,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
Notification.taskInfo('Create new config file for your TYPO3 site extension');
|
|
58
|
+
|
|
59
|
+
rl.question('TYPO3 extension name (/typo3conf/ext/)? i.e. "site_demo": ', (extName) => {
|
|
60
|
+
rl.question('Package Name? i.e. "demo": ', (pkgName) => {
|
|
61
|
+
Create.createConfigFile(args.sitesConfigPath, `${pkgName}.package.js`, extName, pkgName);
|
|
62
|
+
rl.close();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|