@madgex/fert 1.3.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/.eslintignore +8 -0
- package/.eslintrc.js +15 -0
- package/.github/workflows/commits.yml +14 -0
- package/.github/workflows/release.yml +29 -0
- package/.husky/commit-msg +4 -0
- package/.husky/pre-commit +4 -0
- package/.prettierignore +2 -0
- package/.prettierrc.js +8 -0
- package/README.md +232 -0
- package/bin/cli.js +68 -0
- package/bin/commands/build-tasks/build-external-assets.js +16 -0
- package/bin/commands/build-tasks/build-tokens.js +119 -0
- package/bin/commands/build-tasks/bundle-ds-css.js +74 -0
- package/bin/commands/build-tasks/bundle-entry.js +43 -0
- package/bin/commands/build.js +42 -0
- package/bin/commands/dev-server.js +50 -0
- package/bin/commands/init.js +207 -0
- package/bin/commands/publish-tasks/asset-store-uploader.js +94 -0
- package/bin/commands/publish-tasks/get-aws-parameter.js +41 -0
- package/bin/commands/publish.js +51 -0
- package/bin/utils/cpid-lookup.js +47 -0
- package/bin/utils/index.js +121 -0
- package/bin/utils/resolve-external-assets.js +77 -0
- package/commitlint.config.cjs +1 -0
- package/constants.js +36 -0
- package/delivery/git.cer +22 -0
- package/delivery/jenkinsfile +93 -0
- package/package.json +84 -0
- package/repo-templates/globals/fert.config.js +4 -0
- package/repo-templates/globals/jenkinsfile +4 -0
- package/repo-templates/template-basic/_gitignore +5 -0
- package/repo-templates/template-basic/brand.json +21 -0
- package/repo-templates/template-basic/package.json +13 -0
- package/repo-templates/template-basic/public/favicon.ico +0 -0
- package/repo-templates/template-basic/public/fonts/mdgx-icons.eot +0 -0
- package/repo-templates/template-basic/public/fonts/mdgx-icons.svg +71 -0
- package/repo-templates/template-basic/public/fonts/mdgx-icons.ttf +0 -0
- package/repo-templates/template-basic/public/fonts/mdgx-icons.woff +0 -0
- package/repo-templates/template-basic/public/fonts/my-font.woff +1 -0
- package/repo-templates/template-basic/public/images/logo.png +0 -0
- package/repo-templates/template-basic/src/css/styles.scss +12 -0
- package/repo-templates/template-basic/src/index.js +3 -0
- package/repo-templates/template-basic/templates/footer.njk +14 -0
- package/repo-templates/template-basic/templates/header.njk +14 -0
- package/repo-templates/template-bigworkbag/_gitignore +5 -0
- package/repo-templates/template-bigworkbag/brand.json +21 -0
- package/repo-templates/template-bigworkbag/package.json +13 -0
- package/repo-templates/template-bigworkbag/public/favicon.ico +0 -0
- package/repo-templates/template-bigworkbag/public/fonts/mdgx-icons.eot +0 -0
- package/repo-templates/template-bigworkbag/public/fonts/mdgx-icons.svg +71 -0
- package/repo-templates/template-bigworkbag/public/fonts/mdgx-icons.ttf +0 -0
- package/repo-templates/template-bigworkbag/public/fonts/mdgx-icons.woff +0 -0
- package/repo-templates/template-bigworkbag/public/fonts/my-font.woff +1 -0
- package/repo-templates/template-bigworkbag/public/images/logo.png +0 -0
- package/repo-templates/template-bigworkbag/public/images/user-menu-pointer.svg +4 -0
- package/repo-templates/template-bigworkbag/src/css/breakpoints.scss +17 -0
- package/repo-templates/template-bigworkbag/src/css/clicky-menu.scss +52 -0
- package/repo-templates/template-bigworkbag/src/css/desktop-main-nav.scss +25 -0
- package/repo-templates/template-bigworkbag/src/css/desktop-user-nav.scss +127 -0
- package/repo-templates/template-bigworkbag/src/css/footer.scss +77 -0
- package/repo-templates/template-bigworkbag/src/css/header-top.scss +29 -0
- package/repo-templates/template-bigworkbag/src/css/leaderboard-ad.scss +22 -0
- package/repo-templates/template-bigworkbag/src/css/mobile-main-nav.scss +68 -0
- package/repo-templates/template-bigworkbag/src/css/mobile-user-nav.scss +49 -0
- package/repo-templates/template-bigworkbag/src/css/reset.scss +91 -0
- package/repo-templates/template-bigworkbag/src/css/styles.scss +19 -0
- package/repo-templates/template-bigworkbag/src/css/top-bar.scss +13 -0
- package/repo-templates/template-bigworkbag/src/css/typography.scss +20 -0
- package/repo-templates/template-bigworkbag/src/css/util.scss +28 -0
- package/repo-templates/template-bigworkbag/src/css/variables.scss +9 -0
- package/repo-templates/template-bigworkbag/src/index.js +3 -0
- package/repo-templates/template-bigworkbag/src/js/clicky-menus.js +178 -0
- package/repo-templates/template-bigworkbag/src/js/no-js.js +10 -0
- package/repo-templates/template-bigworkbag/templates/context/footer-nav.njk +27 -0
- package/repo-templates/template-bigworkbag/templates/context/main-nav.njk +32 -0
- package/repo-templates/template-bigworkbag/templates/context/user-nav.njk +17 -0
- package/repo-templates/template-bigworkbag/templates/footer.njk +68 -0
- package/repo-templates/template-bigworkbag/templates/header.njk +54 -0
- package/repo-templates/template-bigworkbag/templates/includes/desktop-main-nav-items.njk +18 -0
- package/repo-templates/template-bigworkbag/templates/includes/desktop-user-nav/loggedin-items.njk +28 -0
- package/repo-templates/template-bigworkbag/templates/includes/desktop-user-nav/loggedout-items.njk +9 -0
- package/repo-templates/template-bigworkbag/templates/includes/desktop-user-nav/submenu-items.njk +18 -0
- package/repo-templates/template-bigworkbag/templates/includes/desktop-user-nav/user-nav.njk +24 -0
- package/repo-templates/template-bigworkbag/templates/includes/dev-console-context.njk +7 -0
- package/repo-templates/template-bigworkbag/templates/includes/mobile-main-nav-items.njk +25 -0
- package/repo-templates/template-bigworkbag/templates/includes/mobile-user-nav/loggedin-items.njk +33 -0
- package/repo-templates/template-bigworkbag/templates/includes/mobile-user-nav/loggedout-items.njk +16 -0
- package/repo-templates/template-bigworkbag/templates/includes/mobile-user-nav/user-nav.njk +24 -0
- package/repo-templates/template-bigworkbag/templates/svgs/arrow-down.svg +3 -0
- package/repo-templates/template-bigworkbag/templates/svgs/arrow-left.svg +3 -0
- package/repo-templates/template-bigworkbag/templates/svgs/arrow-right.svg +3 -0
- package/repo-templates/template-bigworkbag/templates/svgs/arrow-up.svg +3 -0
- package/repo-templates/template-bigworkbag/templates/svgs/cart.svg +3 -0
- package/repo-templates/template-bigworkbag/templates/svgs/facebook.svg +3 -0
- package/repo-templates/template-bigworkbag/templates/svgs/linkedin.svg +3 -0
- package/repo-templates/template-bigworkbag/templates/svgs/profile.svg +5 -0
- package/repo-templates/template-bigworkbag/templates/svgs/star-filled.svg +3 -0
- package/repo-templates/template-bigworkbag/templates/svgs/star-outline.svg +3 -0
- package/repo-templates/template-bigworkbag/templates/svgs/twitter.svg +3 -0
- package/repo-templates/template-bigworkbag/templates/svgs/youtube.svg +3 -0
- package/repo-templates/template-bigworkbag/templates/translations/da.njk +26 -0
- package/repo-templates/template-bigworkbag/templates/translations/de.njk +26 -0
- package/repo-templates/template-bigworkbag/templates/translations/en.njk +26 -0
- package/repo-templates/template-bigworkbag/templates/translations/es.njk +26 -0
- package/repo-templates/template-bigworkbag/templates/translations/fr.njk +26 -0
- package/repo-templates/template-bigworkbag/templates/translations/nb.njk +26 -0
- package/repo-templates/template-bigworkbag/templates/translations/nl.njk +26 -0
- package/repo-templates/template-bigworkbag/templates/translations/sv.njk +26 -0
- package/repo-templates/template-bigworkbag/templates/translations/zh-cn.njk +26 -0
- package/server/extensions/error-logging.js +25 -0
- package/server/index.js +98 -0
- package/server/plugins/hapi-vite.js +61 -0
- package/server/routes/public.js +29 -0
- package/server/routes/views.js +46 -0
- package/server/templates/furniture.njk +67 -0
- package/server/templates/page1.njk +37 -0
- package/server/view-manager.js +59 -0
- package/shared/Dockerfile.brandingRepoPublish +28 -0
- package/shared/README.md +4 -0
- package/vite.config.js +14 -0
package/.eslintignore
ADDED
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
env: {
|
|
3
|
+
node: true,
|
|
4
|
+
es6: true,
|
|
5
|
+
},
|
|
6
|
+
plugins: ['prettier'],
|
|
7
|
+
extends: ['eslint:recommended', 'plugin:prettier/recommended'],
|
|
8
|
+
parserOptions: {
|
|
9
|
+
requireConfigFile: false,
|
|
10
|
+
ecmaVersion: 'latest',
|
|
11
|
+
},
|
|
12
|
+
rules: {
|
|
13
|
+
'prettier/prettier': 'error',
|
|
14
|
+
},
|
|
15
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
name: Conventional Commit Checker
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [master]
|
|
6
|
+
types: [opened, edited, synchronize]
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
check-for-cc:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- name: check-for-cc
|
|
13
|
+
id: check-for-cc
|
|
14
|
+
uses: agenthunt/conventional-commit-checker-action@v1.0.0
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
on:
|
|
3
|
+
workflow_run:
|
|
4
|
+
workflows: ['tests']
|
|
5
|
+
branches: [master]
|
|
6
|
+
types:
|
|
7
|
+
- completed
|
|
8
|
+
push:
|
|
9
|
+
branches:
|
|
10
|
+
- master
|
|
11
|
+
jobs:
|
|
12
|
+
release:
|
|
13
|
+
name: Release
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout
|
|
17
|
+
uses: actions/checkout@v1
|
|
18
|
+
- name: Setup Node.js
|
|
19
|
+
uses: actions/setup-node@v2
|
|
20
|
+
with:
|
|
21
|
+
cache: npm
|
|
22
|
+
node-version: 14
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: npm ci
|
|
25
|
+
- name: Release
|
|
26
|
+
env:
|
|
27
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
28
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
29
|
+
run: npx semantic-release
|
package/.prettierignore
ADDED
package/.prettierrc.js
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# FERT - proposed approach/readme
|
|
2
|
+
|
|
3
|
+
Madgex brand tooling for anyone.
|
|
4
|
+
|
|
5
|
+
> **F**ront-**e**nd **R**ollout **T**ool – Tooling to help scaffold, develop and deploy Madgex client branding
|
|
6
|
+
|
|
7
|
+
# Why FERT
|
|
8
|
+
|
|
9
|
+
The Madgex job board brands all have a custom headers, footers and their associated JavaScript & CSS. In the past we've struggled with finding an easy local development & roll-out setup. Fert is an attempt to address that.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
* To be a one-stop shop for:
|
|
14
|
+
|
|
15
|
+
* Scaffolding a new project
|
|
16
|
+
|
|
17
|
+
* A dev server to allow easy brand development
|
|
18
|
+
|
|
19
|
+
* Builds distributable assets
|
|
20
|
+
|
|
21
|
+
* Must be able to install via [NPM](https://www.npmjs.com/) or internal registry
|
|
22
|
+
|
|
23
|
+
* Must work cross-platform (Windows and *nix)
|
|
24
|
+
|
|
25
|
+
## A human-first design
|
|
26
|
+
|
|
27
|
+
To empower & serve its users, we should design this CLI with the users in mind. Ensuring it feels as familiar as possible, following established patterns and is has the following:
|
|
28
|
+
|
|
29
|
+
* Easy to learn commands from a inbuilt help screen
|
|
30
|
+
|
|
31
|
+
* Easy to read/understand error messages
|
|
32
|
+
|
|
33
|
+
* Empathy in the error messages – can some helpful context be provided with the error to assist the user remedy the issue?
|
|
34
|
+
|
|
35
|
+
# Under the hood
|
|
36
|
+
|
|
37
|
+
* [Hapi](https://hapi.dev/) is used for the local dev server
|
|
38
|
+
|
|
39
|
+
* [Vite](https://vitejs.dev/) for HMR, serves the JS entry & bundles assets for production
|
|
40
|
+
|
|
41
|
+
* [Style Dictionary](https://amzn.github.io/style-dictionary/#/README) is used to transform Design Tokens into various outputs, inc. JSON, CSS Custom Properties and SCSS variables. The output is built into `public/tokens/`
|
|
42
|
+
|
|
43
|
+
* Chokidar is used to watch for changes in the `templates` and `public/tokens` directories and either refresh the browser page or build a new set of tokens respectively.
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# Configuration
|
|
48
|
+
|
|
49
|
+
There are **three required files** in the root of the branding repo:
|
|
50
|
+
|
|
51
|
+
`brand.json` [required] – a JSON file that supplies the base branding tokens. These values will be merged with the Design System tokens & a full set of branding tokens will be created.
|
|
52
|
+
|
|
53
|
+
e.g.
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"color": {
|
|
58
|
+
"brand": {
|
|
59
|
+
"1": {
|
|
60
|
+
"base": { "value": "#005689" }
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
// more branding tokens applied here...
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`fert.config.js` [required] – a configuration file in the root of the branding repo specifying the following config to both the Fert dev server and the production asset build:
|
|
69
|
+
|
|
70
|
+
| Option | |
|
|
71
|
+
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
72
|
+
| `clientPropertyId` <String> | The `clientPropertyId` associated with the branding repo (required) |
|
|
73
|
+
| `entry` <String> | The JavaScript entry file. Any assets (CSS/SCSS/SVGs) included will be processed and be part of the output. Defaults to `['src/index.js']` |
|
|
74
|
+
|
|
75
|
+
The `entry` will be used by Vite to create production bundles.
|
|
76
|
+
|
|
77
|
+
e.g.
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
module.exports = {
|
|
81
|
+
clientPropertyId: "ff6102ff-0f4b-43d1-a2c7-83b835b8dee5",
|
|
82
|
+
entry: "./src/index.js",
|
|
83
|
+
};
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`jenkinsfile` - A jenkins file containing the pipeline which will build and send the assets to S3. Every push to the repo will trigger a jenkins build automatically. Changes on **master** will trigger a build and send assets to the **production** bucket. Any other branches will send the assets to the jb.dev bucket.
|
|
87
|
+
|
|
88
|
+
# CLI commands
|
|
89
|
+
|
|
90
|
+
The CLI will support 3 main commands: dev server (default command), scaffolding a new project and building production assets.
|
|
91
|
+
|
|
92
|
+
* [Dev server](#dev-server)
|
|
93
|
+
|
|
94
|
+
* [Scaffold](#scaffold)
|
|
95
|
+
|
|
96
|
+
* [Build](#build)
|
|
97
|
+
|
|
98
|
+
* [Publish](#publish)
|
|
99
|
+
|
|
100
|
+
## Dev server
|
|
101
|
+
|
|
102
|
+
`fert`
|
|
103
|
+
|
|
104
|
+
Start the Fert dev server in the current directory.
|
|
105
|
+
|
|
106
|
+
**Usage**
|
|
107
|
+
|
|
108
|
+
`fert [root]`
|
|
109
|
+
|
|
110
|
+
**Outline of implementation**
|
|
111
|
+
|
|
112
|
+
A fast, minimal development server that allows the developer to see the header/footer templates and branding (Design System tokens) specified in the local repo applied to a Design System-based HTML page.
|
|
113
|
+
|
|
114
|
+
The server will be a hapi server, importing the header/footer micro front-end server(s) as dependencies, running all together to render the page.
|
|
115
|
+
|
|
116
|
+
Changes to the local tokens will cause the DS tokens to be rebuilt.
|
|
117
|
+
|
|
118
|
+
Changes to the local `fert.config.js` will be reflected in the dev servers environment.
|
|
119
|
+
|
|
120
|
+
Changes to any local file will be reflected in the developers browser without having to manually refresh.
|
|
121
|
+
|
|
122
|
+
## Scaffold
|
|
123
|
+
|
|
124
|
+
`fert init`
|
|
125
|
+
|
|
126
|
+
When faced with an empty branding repo, this will help the user get started with the boilerplate branding project template
|
|
127
|
+
|
|
128
|
+
**Usage**
|
|
129
|
+
|
|
130
|
+
`fert init [root]`
|
|
131
|
+
|
|
132
|
+
**Options**
|
|
133
|
+
|
|
134
|
+
| Option | |
|
|
135
|
+
| --------- | --------------------------------------------------------------------- |
|
|
136
|
+
| `--template <template>` | Specify the template you wish to use when scaffolding |
|
|
137
|
+
| `--cpid <cpid>` | Specify the clientPropertyId to use in the new project |
|
|
138
|
+
|
|
139
|
+
**Outline of implementation**
|
|
140
|
+
|
|
141
|
+
The init command will clone a well-maintained boilerplate repo into the target directory. It may be good to use a tool like [`degit`](https://www.npmjs.com/package/degit) for faster cloning & not confusing git with nested, hidden `.git` directories.
|
|
142
|
+
|
|
143
|
+
The `--force` option would destructively reset the branding repo to a common baseline, resetting the content.
|
|
144
|
+
|
|
145
|
+
The source boilerplate repo: https://github.com/wiley/madgex-00000000-0000-0000-0000-000000000000
|
|
146
|
+
The `init` command is intended for an automation tool which will create a new branding repo, run this command and commit the new files.
|
|
147
|
+
|
|
148
|
+
## Build
|
|
149
|
+
|
|
150
|
+
`fert build`
|
|
151
|
+
|
|
152
|
+
Process CSS/JS assets specified in `fert.config.js` and copy static assets, including templates for distribution.
|
|
153
|
+
|
|
154
|
+
**Usage**
|
|
155
|
+
|
|
156
|
+
`fert build [root] --only [tokens | assets]`
|
|
157
|
+
|
|
158
|
+
| Option | |
|
|
159
|
+
| ----------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
160
|
+
| `--only [task]` | Specify a single part of the build process to run (`string` \| `tokens` \| `assets`) |
|
|
161
|
+
| `--config <path>` | Override the internal default Vite config & provide a custom `vite.config.js` file to use to build assets. |
|
|
162
|
+
|
|
163
|
+
**Outline of implementation**
|
|
164
|
+
|
|
165
|
+
Using Vite, the `entry` in the `fert.config.js` file is processed and bundled to the `dist` directory.
|
|
166
|
+
|
|
167
|
+
Templates are copied to `dist`.
|
|
168
|
+
|
|
169
|
+
Public assets are copied to `dist`.
|
|
170
|
+
|
|
171
|
+
The resulting `dist` directory is uploaded wholesale to the `assets-store-api` for use in production.
|
|
172
|
+
|
|
173
|
+
Templates & CSS may be processed using the [CSS Modules](https://github.com/css-modules/css-modules) system to encapsulate header/footer styles & prevent bleed into the rest of the page.
|
|
174
|
+
|
|
175
|
+
## Publish
|
|
176
|
+
|
|
177
|
+
`fert publish`
|
|
178
|
+
|
|
179
|
+
**Usage**
|
|
180
|
+
|
|
181
|
+
`fert publish [root] --target [target]`
|
|
182
|
+
|
|
183
|
+
| Option | |
|
|
184
|
+
| ---------- | ---------------------------------------------------------------------------- |
|
|
185
|
+
| `--target` | Where to publish the `dist` directory assets.<br/>`dev` \| `prod` (`string`) |
|
|
186
|
+
|
|
187
|
+
Send all files and directories created in the `dist` directory to either development or production versions of the Asset Store API. Files uploaded to the Asset Store API are available via a CloudFront-based CDN.
|
|
188
|
+
|
|
189
|
+
**Outline of implementation**
|
|
190
|
+
|
|
191
|
+
Index all the files and their paths in the `dist` directory, and using a recursive function upload each item (destructively) to the Asset Store API.
|
|
192
|
+
|
|
193
|
+
The Asset Store API uses a multi-part form upload to PUT files in the client directory. Upload paths are respected, directories are created on the fly.
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
# CI/CD
|
|
198
|
+
|
|
199
|
+
It's intended that the branding repos have their own build/deploy pipeline. Each change that's merged to `master` will trigger a build (`npm run build` as a common entry point) and the resulting output directory (`dist`) is pushed up to the `asset-store-api` for use in production.
|
|
200
|
+
|
|
201
|
+
## `npm scripts`
|
|
202
|
+
|
|
203
|
+
Here are the default npm scripts in a Fert-scaffolded project.
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"scripts": {
|
|
208
|
+
"dev": "fert", // start dev server
|
|
209
|
+
"build": "fert build" // build assets for production
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Its expected that a Jenkins pipeline will run `fert publish` to send all built assets to the Asset Store API.
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
# @madgex/boilerplate-utils
|
|
219
|
+
|
|
220
|
+
A collection of utilities for use in branding projects, e.g.
|
|
221
|
+
|
|
222
|
+
* Hamburger nav HTML/CSS/JS
|
|
223
|
+
|
|
224
|
+
* common SCSS
|
|
225
|
+
|
|
226
|
+
* SVGs
|
|
227
|
+
|
|
228
|
+
* templates/macros
|
|
229
|
+
|
|
230
|
+
If needed, this package can be `npm install`ed in the branding project & consumed from the JS/SCSS.
|
|
231
|
+
|
|
232
|
+
Templates/macros will have to be copied into the branding repo as they won't be visible/available to the server rendering the template.
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const cli = require('cac')('fert');
|
|
6
|
+
const { VERSION } = require('../constants');
|
|
7
|
+
const { printBanner } = require('./utils/index.js');
|
|
8
|
+
|
|
9
|
+
const run = () => {
|
|
10
|
+
printBanner();
|
|
11
|
+
|
|
12
|
+
cli
|
|
13
|
+
.command(
|
|
14
|
+
'[root]',
|
|
15
|
+
'Start layout server. Can supply a branding directory if running FERT standalone'
|
|
16
|
+
)
|
|
17
|
+
.alias('dev')
|
|
18
|
+
.option('--open', 'Automatically open the dev server in your browser')
|
|
19
|
+
.option('--host [host]', '[string] specify hostname')
|
|
20
|
+
.option('--port <port>', '[number] specify port')
|
|
21
|
+
.action((...args) => require('./commands/dev-server')(...args));
|
|
22
|
+
|
|
23
|
+
cli
|
|
24
|
+
.command(
|
|
25
|
+
'build [root]',
|
|
26
|
+
'Build project. Can supply a branding directory if running FERT standalone'
|
|
27
|
+
)
|
|
28
|
+
.option('--only <task>', `Only run part of the build [ 'assets', 'tokens']`)
|
|
29
|
+
.option('--config [dir]', 'Use custom rollup config file')
|
|
30
|
+
.action((...args) => require('./commands/build.js')(...args));
|
|
31
|
+
|
|
32
|
+
cli
|
|
33
|
+
.command('publish [root]', 'Publish project to S3')
|
|
34
|
+
.option('--target <env>', 'Environment to publish to, "dev" or "prod"')
|
|
35
|
+
.action((...args) => require('./commands/publish')(...args));
|
|
36
|
+
|
|
37
|
+
cli
|
|
38
|
+
.command('init [root]', 'Create a new branding project')
|
|
39
|
+
.option('--template <template>', 'Template to use when scaffolding project')
|
|
40
|
+
.option(
|
|
41
|
+
'--cpid <cpid>',
|
|
42
|
+
'Specify the clientPropertyId to use in the new project'
|
|
43
|
+
)
|
|
44
|
+
.action((...args) => require('./commands/init')(...args));
|
|
45
|
+
|
|
46
|
+
cli.help();
|
|
47
|
+
cli.version(VERSION);
|
|
48
|
+
cli.parse();
|
|
49
|
+
|
|
50
|
+
// checks for available update
|
|
51
|
+
const pkg = JSON.parse(fs.readFileSync(__dirname + '/../package.json'));
|
|
52
|
+
|
|
53
|
+
if (pkg.version.indexOf('0.0.0') !== 0) {
|
|
54
|
+
require('simple-update-notifier')({ pkg });
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
run();
|
|
60
|
+
} catch (error) {
|
|
61
|
+
if (error.name === 'CACError') {
|
|
62
|
+
console.error(chalk`\n{red ${error.message}}`);
|
|
63
|
+
} else {
|
|
64
|
+
console.error(error);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const Path = require('path');
|
|
2
|
+
const fs = require('fs/promises');
|
|
3
|
+
const { log } = require('../../utils');
|
|
4
|
+
|
|
5
|
+
module.exports = async function buildExternalAssets(fertConfig) {
|
|
6
|
+
const { externalAssets, workingDir } = fertConfig;
|
|
7
|
+
const destination = Path.join(workingDir, `/dist/external-assets.json`);
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
await fs.writeFile(destination, JSON.stringify(externalAssets, null, 2));
|
|
11
|
+
log.success('External assets file created');
|
|
12
|
+
} catch (err) {
|
|
13
|
+
log.error(err);
|
|
14
|
+
throw err;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
const StyleDictionaryPackage = require('style-dictionary');
|
|
2
|
+
const Path = require('path');
|
|
3
|
+
const fs = require('fs/promises');
|
|
4
|
+
const {
|
|
5
|
+
registerTransforms,
|
|
6
|
+
} = require('@madgex/design-system/tasks/registerTransforms');
|
|
7
|
+
const colorTransforms = require('@madgex/design-system/tasks/colorTransforms');
|
|
8
|
+
const { ensureTrailingSlash, log, exists } = require('../../utils');
|
|
9
|
+
const { TMP_DIR } = require('../../../constants');
|
|
10
|
+
|
|
11
|
+
const dsTokensPath = Path.dirname(
|
|
12
|
+
require.resolve('@madgex/design-system/src/tokens/_config.js')
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
// eslint-disable-next-line no-unused-vars
|
|
16
|
+
const createTempBrandFile = async (dir = './') => {
|
|
17
|
+
// Generate unique name to bust style dict cache
|
|
18
|
+
const timestamp = Date.now();
|
|
19
|
+
const tmpBrandFile = Path.join(TMP_DIR, `/fert/brand-${timestamp}.json`);
|
|
20
|
+
const dirPath = Path.dirname(tmpBrandFile);
|
|
21
|
+
|
|
22
|
+
if (!(await exists(dirPath))) {
|
|
23
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return tmpBrandFile;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// Style Dictionary is noisy and annoying, this suppresses its output
|
|
30
|
+
async function runSilently(fn) {
|
|
31
|
+
const originalLog = console.log;
|
|
32
|
+
console.log = () => {};
|
|
33
|
+
await fn();
|
|
34
|
+
console.log = originalLog;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = async function buildCssFromTokens(srcTokensPath, buildPath) {
|
|
38
|
+
srcTokensPath = ensureTrailingSlash(Path.resolve(srcTokensPath));
|
|
39
|
+
buildPath = ensureTrailingSlash(Path.resolve(buildPath));
|
|
40
|
+
|
|
41
|
+
const brandFile = Path.join(srcTokensPath, 'brand.json');
|
|
42
|
+
|
|
43
|
+
if (!(await exists(buildPath))) {
|
|
44
|
+
await fs.mkdir(buildPath, { recursive: true });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Fetch the file so we can transform the colours in style dictionary
|
|
48
|
+
const brandObj = JSON.parse(
|
|
49
|
+
await fs.readFile(brandFile, { encoding: 'utf8' })
|
|
50
|
+
);
|
|
51
|
+
const tmpBrandFile = await createTempBrandFile(srcTokensPath);
|
|
52
|
+
|
|
53
|
+
await fs.writeFile(
|
|
54
|
+
Path.join(tmpBrandFile),
|
|
55
|
+
JSON.stringify(colorTransforms(brandObj))
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
// TODO - Investigate whether we can retrieve from DS instead of redefining
|
|
59
|
+
// e.g. const { registerTransforms } = require('@madgex/design-system/tasks/registerTransforms');
|
|
60
|
+
const transforms = [
|
|
61
|
+
'attribute/cti',
|
|
62
|
+
'name/cti/kebab',
|
|
63
|
+
'color/css',
|
|
64
|
+
'css/rawData',
|
|
65
|
+
];
|
|
66
|
+
const prefix = 'mds';
|
|
67
|
+
|
|
68
|
+
// TODO - Investigate whether we can retrieve from DS instead of redefining
|
|
69
|
+
const styleDictionaryConfig = {
|
|
70
|
+
include: [Path.join(dsTokensPath, '*.json')],
|
|
71
|
+
source: [tmpBrandFile],
|
|
72
|
+
platforms: {
|
|
73
|
+
'scss-variables': {
|
|
74
|
+
transforms,
|
|
75
|
+
prefix,
|
|
76
|
+
buildPath: Path.join(buildPath, 'scss/'),
|
|
77
|
+
files: [
|
|
78
|
+
{
|
|
79
|
+
destination: 'index.scss',
|
|
80
|
+
format: 'scss/map-deep',
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
'css-variables': {
|
|
85
|
+
transforms,
|
|
86
|
+
prefix,
|
|
87
|
+
buildPath: Path.join(buildPath, 'css-vars/'),
|
|
88
|
+
files: [
|
|
89
|
+
{
|
|
90
|
+
destination: `variables.css`,
|
|
91
|
+
format: 'css/variables',
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
'json-variables': {
|
|
96
|
+
transforms,
|
|
97
|
+
prefix,
|
|
98
|
+
buildPath: Path.join(buildPath, 'json/'),
|
|
99
|
+
files: [
|
|
100
|
+
{
|
|
101
|
+
destination: `variables.json`,
|
|
102
|
+
format: 'json/nested',
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// Use StyleDictionary to build a tokens SCSS file
|
|
110
|
+
const StyleDictionary = StyleDictionaryPackage.extend(styleDictionaryConfig);
|
|
111
|
+
|
|
112
|
+
await registerTransforms(StyleDictionary);
|
|
113
|
+
await runSilently(StyleDictionary.buildAllPlatforms.bind(StyleDictionary));
|
|
114
|
+
|
|
115
|
+
// clean-up temp SD file
|
|
116
|
+
await fs.unlink(tmpBrandFile);
|
|
117
|
+
|
|
118
|
+
log.success('Token build complete.');
|
|
119
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const path = require('node:path');
|
|
2
|
+
const fsp = require('node:fs/promises');
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
const vite = require('vite');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
|
|
7
|
+
// TODO: delete me when DS is driven by CSS Custom Ppoperties
|
|
8
|
+
|
|
9
|
+
module.exports = async (viteConfig) => {
|
|
10
|
+
const dsBundledViteConfig = { ...viteConfig };
|
|
11
|
+
|
|
12
|
+
// create ds-bundled vite build in-memory
|
|
13
|
+
_.merge(dsBundledViteConfig, {
|
|
14
|
+
logLevel: 'silent',
|
|
15
|
+
build: {
|
|
16
|
+
write: false,
|
|
17
|
+
rollupOptions: {
|
|
18
|
+
output: {
|
|
19
|
+
assetFileNames: 'assets/[name]-ds-[hash].[ext]',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
css: {
|
|
24
|
+
preprocessorOptions: {
|
|
25
|
+
scss: {
|
|
26
|
+
additionalData: `
|
|
27
|
+
@import "../../public/tokens/scss/index.scss";
|
|
28
|
+
@import "@madgex/design-system/src/scss/import.scss";
|
|
29
|
+
`, // all scss processed files gets this injected at the top
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const dsBuild = await vite.build(dsBundledViteConfig);
|
|
36
|
+
const { output: files } = Array.isArray(dsBuild) ? dsBuild[0] : dsBuild;
|
|
37
|
+
|
|
38
|
+
// write just the CSS file to disk
|
|
39
|
+
for (const file of files) {
|
|
40
|
+
if (file.name !== 'style.css') {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const cssFileContent = file.source;
|
|
44
|
+
await fsp.writeFile(
|
|
45
|
+
path.resolve('dist', file.fileName),
|
|
46
|
+
cssFileContent,
|
|
47
|
+
'utf8'
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// read the manifest.json
|
|
51
|
+
const manifestPath = path.resolve('dist', 'manifest.json');
|
|
52
|
+
const manifestStr = await fsp.readFile(manifestPath);
|
|
53
|
+
const manifest = JSON.parse(manifestStr);
|
|
54
|
+
|
|
55
|
+
// add entry to manifest.json
|
|
56
|
+
const dsEntryName = file.name
|
|
57
|
+
.split('.')
|
|
58
|
+
.map((part, i) => (i === 0 ? `${part}-ds` : part))
|
|
59
|
+
.join('.');
|
|
60
|
+
manifest[dsEntryName] = { ...manifest[file.name] };
|
|
61
|
+
manifest[dsEntryName].file = file.fileName;
|
|
62
|
+
|
|
63
|
+
// write new manifest
|
|
64
|
+
await fsp.writeFile(
|
|
65
|
+
manifestPath,
|
|
66
|
+
JSON.stringify(manifest, null, 2),
|
|
67
|
+
'utf8'
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
console.log(
|
|
71
|
+
`\nUpdated build & manifest with DS-bundled CSS file: ${chalk.magenta(file.fileName)}\n` // prettier-ignore
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const _ = require('lodash');
|
|
3
|
+
const vite = require('vite');
|
|
4
|
+
const updateBuildWithBundledDsCSS = require('./bundle-ds-css');
|
|
5
|
+
const buildExternalAssets = require('./build-external-assets');
|
|
6
|
+
const { log } = require('../../utils');
|
|
7
|
+
|
|
8
|
+
module.exports = async (fertConfig, options = {}) => {
|
|
9
|
+
let dynamicOptions = {};
|
|
10
|
+
let viteConfig = {};
|
|
11
|
+
|
|
12
|
+
if (options.config) {
|
|
13
|
+
viteConfig = require(path.resolve(fertConfig.workingDir, options.config));
|
|
14
|
+
} else {
|
|
15
|
+
viteConfig = require(path.resolve(__dirname, '../../../vite.config.js'));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
dynamicOptions = {
|
|
19
|
+
root: path.resolve(fertConfig.workingDir),
|
|
20
|
+
base: '/_/jobseekers-frontend/',
|
|
21
|
+
build: {
|
|
22
|
+
cssCodeSplit: false, // important: to get a single, style.css file output
|
|
23
|
+
outDir: path.resolve(fertConfig.workingDir, 'dist'),
|
|
24
|
+
rollupOptions: {
|
|
25
|
+
input: path.resolve(
|
|
26
|
+
fertConfig.workingDir,
|
|
27
|
+
fertConfig.entry || './src/index.js'
|
|
28
|
+
),
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
_.merge(viteConfig, dynamicOptions);
|
|
34
|
+
|
|
35
|
+
await vite.build(viteConfig);
|
|
36
|
+
|
|
37
|
+
// second build - this time with the DS included in the CSS bundle
|
|
38
|
+
await updateBuildWithBundledDsCSS(viteConfig);
|
|
39
|
+
|
|
40
|
+
await buildExternalAssets(fertConfig);
|
|
41
|
+
|
|
42
|
+
log.success('Assets built.');
|
|
43
|
+
};
|