@openedx/frontend-build 12.10.0-alpha.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.
Files changed (235) hide show
  1. package/.eslintignore +5 -0
  2. package/.eslintrc.js +10 -0
  3. package/.github/workflows/add-depr-ticket-to-depr-board.yml +19 -0
  4. package/.github/workflows/add-remove-label-on-comment.yml +20 -0
  5. package/.github/workflows/ci.yml +30 -0
  6. package/.github/workflows/commitlint.yml +20 -0
  7. package/.github/workflows/lockfileversion-check.yml +13 -0
  8. package/.github/workflows/release.yml +34 -0
  9. package/.github/workflows/self-assign-issue.yml +12 -0
  10. package/.github/workflows/sync-master-alpha.yml +35 -0
  11. package/.nvmrc +1 -0
  12. package/LICENSE +661 -0
  13. package/README.md +314 -0
  14. package/bin/fedx-scripts.js +88 -0
  15. package/config/.eslintrc.js +46 -0
  16. package/config/babel-preserve-modules.config.js +30 -0
  17. package/config/babel-typescript.config.js +5 -0
  18. package/config/babel.config.js +41 -0
  19. package/config/getLocalAliases.js +67 -0
  20. package/config/jest/fallback.env.config.js +12 -0
  21. package/config/jest/fileMock.js +1 -0
  22. package/config/jest/setupTest.js +10 -0
  23. package/config/jest/svgrMock.js +4 -0
  24. package/config/jest.config.js +45 -0
  25. package/config/webpack.common.config.js +40 -0
  26. package/config/webpack.dev-stage.config.js +191 -0
  27. package/config/webpack.dev.config.js +193 -0
  28. package/config/webpack.prod.config.js +219 -0
  29. package/coverage/clover.xml +6 -0
  30. package/coverage/coverage-final.json +1 -0
  31. package/coverage/lcov-report/base.css +224 -0
  32. package/coverage/lcov-report/block-navigation.js +87 -0
  33. package/coverage/lcov-report/favicon.png +0 -0
  34. package/coverage/lcov-report/index.html +101 -0
  35. package/coverage/lcov-report/prettify.css +1 -0
  36. package/coverage/lcov-report/prettify.js +2 -0
  37. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  38. package/coverage/lcov-report/sorter.js +196 -0
  39. package/coverage/lcov.info +0 -0
  40. package/docs/0001-non-usage-of-gatsby.rst +37 -0
  41. package/docs/0002-js-environment-config.md +47 -0
  42. package/docs/0003-fedx-scripts-serve.md +37 -0
  43. package/example/.env +0 -0
  44. package/example/.env.development +3 -0
  45. package/example/.env.test +2 -0
  46. package/example/.eslintignore +5 -0
  47. package/example/.eslintrc.js +3 -0
  48. package/example/dist/1382e1cbf8d733d7301cdd212192bfea.jpg +0 -0
  49. package/example/dist/6.4a131009e103f9d0c995.js +3 -0
  50. package/example/dist/6.4a131009e103f9d0c995.js.LICENSE.txt +41 -0
  51. package/example/dist/6.4a131009e103f9d0c995.js.map +1 -0
  52. package/example/dist/app.04e87df21a6686d7d2a5.css +3 -0
  53. package/example/dist/app.04e87df21a6686d7d2a5.css.map +1 -0
  54. package/example/dist/app.04e87df21a6686d7d2a5.js +2 -0
  55. package/example/dist/app.04e87df21a6686d7d2a5.js.map +1 -0
  56. package/example/dist/babel/App.js +94 -0
  57. package/example/dist/babel/App.js.map +1 -0
  58. package/example/dist/babel/App.test.jsx +11 -0
  59. package/example/dist/babel/Image.tsx +16 -0
  60. package/example/dist/babel/__snapshots__/App.test.jsx.snap +120 -0
  61. package/example/dist/babel/apple.jpg +0 -0
  62. package/example/dist/babel/apple.svg +1 -0
  63. package/example/dist/babel/index.js +13 -0
  64. package/example/dist/babel/index.js.map +1 -0
  65. package/example/dist/babel/style.scss +9 -0
  66. package/example/dist/cb28cdb1468c915e27e5cec9af64f22f.svg +1 -0
  67. package/example/dist/index.html +4 -0
  68. package/example/dist/report.html +39 -0
  69. package/example/dist/runtime.a27e316c40c13d63555d.js +2 -0
  70. package/example/dist/runtime.a27e316c40c13d63555d.js.map +1 -0
  71. package/example/env.config.js +6 -0
  72. package/example/node_modules/.package-lock.json +98 -0
  73. package/example/node_modules/js-tokens/CHANGELOG.md +151 -0
  74. package/example/node_modules/js-tokens/LICENSE +21 -0
  75. package/example/node_modules/js-tokens/README.md +240 -0
  76. package/example/node_modules/js-tokens/index.js +23 -0
  77. package/example/node_modules/js-tokens/package.json +30 -0
  78. package/example/node_modules/loose-envify/LICENSE +21 -0
  79. package/example/node_modules/loose-envify/README.md +45 -0
  80. package/example/node_modules/loose-envify/cli.js +16 -0
  81. package/example/node_modules/loose-envify/custom.js +4 -0
  82. package/example/node_modules/loose-envify/index.js +3 -0
  83. package/example/node_modules/loose-envify/loose-envify.js +36 -0
  84. package/example/node_modules/loose-envify/package.json +36 -0
  85. package/example/node_modules/loose-envify/replace.js +65 -0
  86. package/example/node_modules/object-assign/index.js +90 -0
  87. package/example/node_modules/object-assign/license +21 -0
  88. package/example/node_modules/object-assign/package.json +42 -0
  89. package/example/node_modules/object-assign/readme.md +61 -0
  90. package/example/node_modules/prop-types/LICENSE +21 -0
  91. package/example/node_modules/prop-types/README.md +302 -0
  92. package/example/node_modules/prop-types/checkPropTypes.js +103 -0
  93. package/example/node_modules/prop-types/factory.js +19 -0
  94. package/example/node_modules/prop-types/factoryWithThrowingShims.js +65 -0
  95. package/example/node_modules/prop-types/factoryWithTypeCheckers.js +610 -0
  96. package/example/node_modules/prop-types/index.js +19 -0
  97. package/example/node_modules/prop-types/lib/ReactPropTypesSecret.js +12 -0
  98. package/example/node_modules/prop-types/lib/has.js +1 -0
  99. package/example/node_modules/prop-types/package.json +60 -0
  100. package/example/node_modules/prop-types/prop-types.js +1315 -0
  101. package/example/node_modules/prop-types/prop-types.min.js +1 -0
  102. package/example/node_modules/react/LICENSE +21 -0
  103. package/example/node_modules/react/README.md +13 -0
  104. package/example/node_modules/react/build-info.json +8 -0
  105. package/example/node_modules/react/cjs/react-jsx-dev-runtime.development.js +889 -0
  106. package/example/node_modules/react/cjs/react-jsx-dev-runtime.production.min.js +9 -0
  107. package/example/node_modules/react/cjs/react-jsx-runtime.development.js +911 -0
  108. package/example/node_modules/react/cjs/react-jsx-runtime.production.min.js +10 -0
  109. package/example/node_modules/react/cjs/react.development.js +1912 -0
  110. package/example/node_modules/react/cjs/react.production.min.js +25 -0
  111. package/example/node_modules/react/index.js +7 -0
  112. package/example/node_modules/react/jsx-dev-runtime.js +7 -0
  113. package/example/node_modules/react/jsx-runtime.js +7 -0
  114. package/example/node_modules/react/package.json +44 -0
  115. package/example/node_modules/react/umd/react.development.js +3318 -0
  116. package/example/node_modules/react/umd/react.production.min.js +32 -0
  117. package/example/node_modules/react/umd/react.profiling.min.js +39 -0
  118. package/example/node_modules/react-dom/LICENSE +21 -0
  119. package/example/node_modules/react-dom/README.md +54 -0
  120. package/example/node_modules/react-dom/build-info.json +8 -0
  121. package/example/node_modules/react-dom/cjs/react-dom-server.browser.development.js +4043 -0
  122. package/example/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js +54 -0
  123. package/example/node_modules/react-dom/cjs/react-dom-server.node.development.js +4085 -0
  124. package/example/node_modules/react-dom/cjs/react-dom-server.node.production.min.js +55 -0
  125. package/example/node_modules/react-dom/cjs/react-dom-test-utils.development.js +1480 -0
  126. package/example/node_modules/react-dom/cjs/react-dom-test-utils.production.min.js +35 -0
  127. package/example/node_modules/react-dom/cjs/react-dom-unstable-fizz.browser.development.js +141 -0
  128. package/example/node_modules/react-dom/cjs/react-dom-unstable-fizz.browser.production.min.js +11 -0
  129. package/example/node_modules/react-dom/cjs/react-dom-unstable-fizz.node.development.js +162 -0
  130. package/example/node_modules/react-dom/cjs/react-dom-unstable-fizz.node.production.min.js +12 -0
  131. package/example/node_modules/react-dom/cjs/react-dom-unstable-native-dependencies.development.js +1629 -0
  132. package/example/node_modules/react-dom/cjs/react-dom-unstable-native-dependencies.production.min.js +31 -0
  133. package/example/node_modules/react-dom/cjs/react-dom.development.js +25012 -0
  134. package/example/node_modules/react-dom/cjs/react-dom.production.min.js +292 -0
  135. package/example/node_modules/react-dom/cjs/react-dom.profiling.min.js +299 -0
  136. package/example/node_modules/react-dom/index.js +38 -0
  137. package/example/node_modules/react-dom/package.json +60 -0
  138. package/example/node_modules/react-dom/profiling.js +38 -0
  139. package/example/node_modules/react-dom/server.browser.js +7 -0
  140. package/example/node_modules/react-dom/server.js +3 -0
  141. package/example/node_modules/react-dom/server.node.js +7 -0
  142. package/example/node_modules/react-dom/test-utils.js +7 -0
  143. package/example/node_modules/react-dom/umd/react-dom-server.browser.development.js +4147 -0
  144. package/example/node_modules/react-dom/umd/react-dom-server.browser.production.min.js +45 -0
  145. package/example/node_modules/react-dom/umd/react-dom-test-utils.development.js +1499 -0
  146. package/example/node_modules/react-dom/umd/react-dom-test-utils.production.min.js +30 -0
  147. package/example/node_modules/react-dom/umd/react-dom-unstable-fizz.browser.development.js +141 -0
  148. package/example/node_modules/react-dom/umd/react-dom-unstable-fizz.browser.production.min.js +10 -0
  149. package/example/node_modules/react-dom/umd/react-dom-unstable-native-dependencies.development.js +1628 -0
  150. package/example/node_modules/react-dom/umd/react-dom-unstable-native-dependencies.production.min.js +28 -0
  151. package/example/node_modules/react-dom/umd/react-dom.development.js +25147 -0
  152. package/example/node_modules/react-dom/umd/react-dom.production.min.js +239 -0
  153. package/example/node_modules/react-dom/umd/react-dom.profiling.min.js +247 -0
  154. package/example/node_modules/react-dom/unstable-fizz.browser.js +7 -0
  155. package/example/node_modules/react-dom/unstable-fizz.js +3 -0
  156. package/example/node_modules/react-dom/unstable-fizz.node.js +7 -0
  157. package/example/node_modules/react-dom/unstable-native-dependencies.js +7 -0
  158. package/example/node_modules/react-is/LICENSE +21 -0
  159. package/example/node_modules/react-is/README.md +104 -0
  160. package/example/node_modules/react-is/build-info.json +8 -0
  161. package/example/node_modules/react-is/cjs/react-is.development.js +181 -0
  162. package/example/node_modules/react-is/cjs/react-is.production.min.js +15 -0
  163. package/example/node_modules/react-is/index.js +7 -0
  164. package/example/node_modules/react-is/package.json +27 -0
  165. package/example/node_modules/react-is/umd/react-is.development.js +181 -0
  166. package/example/node_modules/react-is/umd/react-is.production.min.js +13 -0
  167. package/example/node_modules/react-test-renderer/LICENSE +21 -0
  168. package/example/node_modules/react-test-renderer/README.md +26 -0
  169. package/example/node_modules/react-test-renderer/build-info.json +8 -0
  170. package/example/node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js +1019 -0
  171. package/example/node_modules/react-test-renderer/cjs/react-test-renderer-shallow.production.min.js +35 -0
  172. package/example/node_modules/react-test-renderer/cjs/react-test-renderer.development.js +15596 -0
  173. package/example/node_modules/react-test-renderer/cjs/react-test-renderer.production.min.js +181 -0
  174. package/example/node_modules/react-test-renderer/index.js +7 -0
  175. package/example/node_modules/react-test-renderer/package.json +41 -0
  176. package/example/node_modules/react-test-renderer/shallow.js +7 -0
  177. package/example/node_modules/react-test-renderer/umd/react-test-renderer-shallow.development.js +1176 -0
  178. package/example/node_modules/react-test-renderer/umd/react-test-renderer-shallow.production.min.js +31 -0
  179. package/example/node_modules/react-test-renderer/umd/react-test-renderer.development.js +15709 -0
  180. package/example/node_modules/react-test-renderer/umd/react-test-renderer.production.min.js +151 -0
  181. package/example/node_modules/scheduler/LICENSE +21 -0
  182. package/example/node_modules/scheduler/README.md +9 -0
  183. package/example/node_modules/scheduler/build-info.json +8 -0
  184. package/example/node_modules/scheduler/cjs/scheduler-tracing.development.js +349 -0
  185. package/example/node_modules/scheduler/cjs/scheduler-tracing.production.min.js +10 -0
  186. package/example/node_modules/scheduler/cjs/scheduler-tracing.profiling.min.js +17 -0
  187. package/example/node_modules/scheduler/cjs/scheduler-unstable_mock.development.js +857 -0
  188. package/example/node_modules/scheduler/cjs/scheduler-unstable_mock.production.min.js +20 -0
  189. package/example/node_modules/scheduler/cjs/scheduler.development.js +858 -0
  190. package/example/node_modules/scheduler/cjs/scheduler.production.min.js +21 -0
  191. package/example/node_modules/scheduler/index.js +7 -0
  192. package/example/node_modules/scheduler/package.json +39 -0
  193. package/example/node_modules/scheduler/tracing-profiling.js +7 -0
  194. package/example/node_modules/scheduler/tracing.js +7 -0
  195. package/example/node_modules/scheduler/umd/scheduler-tracing.development.js +80 -0
  196. package/example/node_modules/scheduler/umd/scheduler-tracing.production.min.js +80 -0
  197. package/example/node_modules/scheduler/umd/scheduler-tracing.profiling.min.js +80 -0
  198. package/example/node_modules/scheduler/umd/scheduler-unstable_mock.development.js +857 -0
  199. package/example/node_modules/scheduler/umd/scheduler-unstable_mock.production.min.js +17 -0
  200. package/example/node_modules/scheduler/umd/scheduler.development.js +152 -0
  201. package/example/node_modules/scheduler/umd/scheduler.production.min.js +146 -0
  202. package/example/node_modules/scheduler/umd/scheduler.profiling.min.js +146 -0
  203. package/example/node_modules/scheduler/unstable_mock.js +7 -0
  204. package/example/package-lock.json +110 -0
  205. package/example/package.json +24 -0
  206. package/example/public/index.html +13 -0
  207. package/example/src/App.jsx +43 -0
  208. package/example/src/App.test.jsx +11 -0
  209. package/example/src/Image.tsx +16 -0
  210. package/example/src/__snapshots__/App.test.jsx.snap +120 -0
  211. package/example/src/apple.jpg +0 -0
  212. package/example/src/apple.svg +1 -0
  213. package/example/src/index.jsx +13 -0
  214. package/example/src/style.scss +9 -0
  215. package/example/tsconfig.json +16 -0
  216. package/index.js +7 -0
  217. package/lib/ConfigPreset.js +28 -0
  218. package/lib/createConfig.js +7 -0
  219. package/lib/formatter.js +10 -0
  220. package/lib/getBaseConfig.js +9 -0
  221. package/lib/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.js +86 -0
  222. package/lib/plugins/html-webpack-new-relic-plugin/LICENSE +21 -0
  223. package/lib/plugins/html-webpack-new-relic-plugin/README.md +7 -0
  224. package/lib/plugins/html-webpack-new-relic-plugin/index.js +3 -0
  225. package/lib/plugins/html-webpack-new-relic-plugin/test/HtmlWebpackNewRelicPlugin.test.js +80 -0
  226. package/lib/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +1 -0
  227. package/lib/presets.js +75 -0
  228. package/lib/resolveFilepaths.js +14 -0
  229. package/lib/resolvePrivateEnvConfig.js +15 -0
  230. package/lib/scripts/serve.js +78 -0
  231. package/openedx.yaml +10 -0
  232. package/package.json +101 -0
  233. package/renovate.json +22 -0
  234. package/smoke-test.sh +11 -0
  235. package/tsconfig.json +22 -0
package/README.md ADDED
@@ -0,0 +1,314 @@
1
+ # frontend-build
2
+
3
+ [![Build
4
+ Status](https://api.travis-ci.com/edx/frontend-build.svg?branch=master)](https://travis-ci.com/edx/frontend-build)
5
+ ![npm\_version](https://img.shields.io/npm/v/@openedx/frontend-build.svg)
6
+ [![Codecov](https://img.shields.io/codecov/c/github/edx/frontend-build)](https://codecov.io/gh/edx/frontend-build)
7
+ [![license](https://img.shields.io/npm/l/@openedx/frontend-build.svg)](https://github.com/edx-unsupported/frontend-base/blob/master/LICENSE)
8
+
9
+ ## Purpose
10
+
11
+ The purpose of this package is to provide a common sense foundation and
12
+ setup for frontend projects including:
13
+
14
+ - linting (eslint)
15
+ - testing (jest)
16
+ - development server (webpack-dev-server)
17
+ - build (webpack)
18
+
19
+ This package can serve as a single dev dependency replacing a large
20
+ number of dev and build dependencies. It aims to provide common sense
21
+ defaults that should be good for most edX projects out of the box, but
22
+ can extended or overridden where needed.
23
+
24
+ ## Cloning and Startup
25
+
26
+ ``` {.}
27
+ 1. Clone your new repo:
28
+
29
+ ``git clone https://github.com/openedx/frontend-build.git``
30
+
31
+ 2. Use node v18.x.
32
+
33
+ The current version of the micro-frontend build scripts support node 18.
34
+ Using other major versions of node *may* work, but this is unsupported. For
35
+ convenience, this repository includes an .nvmrc file to help in setting the
36
+ correct node version via `nvm <https://github.com/nvm-sh/nvm>`_.
37
+
38
+ 3. Install npm dependencies:
39
+
40
+ ``cd frontend-build && npm ci``
41
+ ```
42
+
43
+ ## Usage
44
+
45
+ CLI commands are structured: `fedx-scripts <targetScript> <options>`.
46
+ Options are passed on to the target script, so refer to each target
47
+ script\'s CLI documentation to learn what options are available. Example
48
+ package.json:
49
+
50
+ {
51
+ "scripts": {
52
+ "build": "fedx-scripts webpack",
53
+ "i18n_extract": "fedx-scripts formatjs extract",
54
+ "lint": "fedx-scripts eslint --ext .jsx,.js .",
55
+ "precommit": "npm run lint",
56
+ "snapshot": "fedx-scripts jest --updateSnapshot",
57
+ "start": "fedx-scripts webpack-dev-server --progress",
58
+ "test": "fedx-scripts jest --coverage --passWithNoTests",
59
+ "serve": "fedx-scripts serve"
60
+ },
61
+ "dependencies": {
62
+ ...
63
+ },
64
+ "devDependencies": {
65
+ "@openedx/frontend-build": "1.0.0"
66
+ }
67
+ }
68
+
69
+ ## Extending or Overriding Config Presets
70
+
71
+ This package contains a set of configuration presets:
72
+
73
+ - webpack-prod (or webpack)
74
+ - webpack-dev (or webpack-dev-server)
75
+ - webpack-dev-stage (for running development apps against stage apis)
76
+ - babel
77
+ - babel-preserve-modules
78
+ - jest
79
+ - eslint
80
+
81
+ If you need to extend or modify a configuration you can add your own
82
+ configuration files, either by extending frontend-build\'s configuration
83
+ files or supplying your own wholesale.
84
+
85
+ Method 1: Extend base config (babel.config.js):
86
+
87
+ const { createConfig } = require('@openedx/frontend-build');
88
+ module.exports = createConfig('babel', {
89
+ /* option overrides or extensions */
90
+ });
91
+
92
+ Method 2: Custom manipulations (babel.config.js):
93
+
94
+ const { getBaseConfig } = require('@openedx/frontend-build');
95
+ const config = getBaseConfig('babel');
96
+
97
+ /* Custom config manipulations */
98
+
99
+ module.exports = config;
100
+
101
+ Frontend build will look in the following locations for configuration
102
+ files in your project.
103
+
104
+ - eslint: `<project_root>/.eslintrc.js`
105
+ - jest: `<project_root>/jest.config.js`
106
+ - babel: `<project_root>/babel.config.js`
107
+ - webpack-prod: `<project_root>/webpack.prod.config.js`
108
+ - webpack-dev-server: `<project_root>/webpack.dev.config.js`
109
+
110
+ You may specify custom config file locations via the command line if you
111
+ prefer a different location. Example package.json:
112
+
113
+ {
114
+ "scripts": {
115
+ "build": "fedx-scripts webpack --config ./config/webpack.config.js",
116
+ "start:stage": "fedx-scripts webpack-dev-server --config webpack.dev-stage.config.js",
117
+ ...
118
+ }
119
+ }
120
+
121
+ Note, specifying a custom config location for babel may cause issues
122
+ with other tools in frontend-build. eslint, jest, webpack, and
123
+ webpack-dev-server configuration presets rely upon the babel config and
124
+ resolve the location of the config file according to the default
125
+ locations described above. If you need to move the babel config file to
126
+ a custom location, you may also need to customize references to its
127
+ location in other configuration files. Please reach out to the FedX team
128
+ if you need to do this and are running into problems.
129
+
130
+ ## Local module configuration for Webpack
131
+
132
+
133
+ The development webpack configuration allows engineers to create a
134
+ \"module.config.js\" file containing local module overrides. This means
135
+ that if you\'re developing a new feature in a shared library
136
+ (\@edx/frontend-platform, \@openedx/paragon, etc.), you can add the local
137
+ location of that repository to your module.config.js file and the
138
+ webpack build for your application will automatically pick it up and use
139
+ it, rather than its node\_modules version of the file.
140
+
141
+ **NOTE: This module.config.js file should be added to your**
142
+ [.gitignore]{.title-ref}.
143
+
144
+ An example module.config.js file looks like the following. You can copy
145
+ this into your application to use local versions of paragon and
146
+ frontend-platform:
147
+
148
+ module.exports = {
149
+ /*
150
+ Modules you want to use from local source code. Adding a module here means that when this app
151
+ runs its build, it'll resolve the source from peer directories of this app.
152
+
153
+ moduleName: the name you use to import code from the module.
154
+ dir: The relative path to the module's source code.
155
+ dist: The sub-directory of the source code where it puts its build artifact. Often "dist".
156
+ */
157
+ localModules: [
158
+ { moduleName: '@openedx/brand', dir: '../src/brand-openedx' }, // replace with your brand checkout
159
+ { moduleName: '@openedx/paragon/scss/core', dir: '../src/paragon', dist: 'scss/core' },
160
+ { moduleName: '@openedx/paragon/icons', dir: '../src/paragon', dist: 'icons' },
161
+ { moduleName: '@openedx/paragon', dir: '../src/paragon', dist: 'dist' },
162
+ { moduleName: '@edx/frontend-platform', dir: '../src/frontend-platform', dist: 'dist' },
163
+ ],
164
+ };
165
+
166
+ ## Steps
167
+
168
+ 1. Copy the `module.config.js` into your frontend app repository,
169
+ modifying it as necessary.
170
+ 2. Run `npm install && npm run build` within any shared NPM package you
171
+ want to use locally.
172
+ 3. Restart your app.
173
+
174
+ ## Notes
175
+
176
+ - The \"dir\" and \"dist\" keys give you granular control over the
177
+ shape of your repository\'s distribution. Paragon, for instance,
178
+ needs two separate entries to pick up both JS and SCSS imports.
179
+ - The directory location `../src` (relative to the root of your
180
+ frontend app repository) is recommended for shared NPM package
181
+ repositories, since it will work whether or not you are running your
182
+ frontend via devstack. If you are *not* running your frontend via
183
+ devstack, then you can place your shared libraries anywhere in your
184
+ file system, updating the \"dir\" key accordingly. To learn more,
185
+ see [this devstack ADR on local
186
+ packages](https://github.com/openedx/devstack/tree/master/docs/decisions/0005-frontend-package-mounts.rst).
187
+ - This mechanism uses Webpack resolve aliases, as documented here:
188
+ <https://webpack.js.org/configuration/resolve/#resolvealias>
189
+
190
+ ## Override default .env.development environment variables with .env.private
191
+
192
+ In some situations, you may want to override development environment
193
+ variables defined in .env.development with private environment variables
194
+ that should never be checked into a repository. For example, a
195
+ .env.development file may contain secrets for a third-party service
196
+ (e.g., Algolia) that you\'d like to use during development but want to
197
+ ensure these secrets are not checked into Git.
198
+
199
+ You may create a [.env.private]{.title-ref} with any overrides of the
200
+ environment settings configured in [.env.development]{.title-ref}.
201
+
202
+ **Note: .env.private should be added to your project\'s .gitignore so it
203
+ does not get checked in.**
204
+
205
+ ## Serving a production Webpack build locally
206
+
207
+ In some scenarios, you may want to run a production Webpack build
208
+ locally. To serve a production build locally:
209
+
210
+ 1. Create an `env.config.js` file containing the configuration for
211
+ local development, with the exception of `NODE_ENV='production'`.
212
+ 2. Run `npm run build` to build the production assets. The output
213
+ assets will rely on the local development configuration specified in
214
+ the prior step.
215
+ 3. Add an NPM script `serve` to your application\'s `package.json`
216
+ (i.e., `"serve": "fedx-scripts serve"`).
217
+ 4. Run `npm run serve` to serve your production build assets. It will
218
+ attempt to run the build on the same port specified in the
219
+ `env.config.js` file.
220
+
221
+ ## Local module configuration for TypeScript
222
+
223
+ #. Create file in repository `tsconfig.json`, with a clause `"extends": "@openedx/frontend-build"`
224
+ #. Set "rootDir" to the root of the source code folders
225
+ #. Set "include" to wildcard patterns specifying the subdirectories/files under rootDir where source code can be found
226
+ #. Include any wildcards under rootDir that should be excluded using "exclude"
227
+
228
+ ```Sample json
229
+ {
230
+ "extends": "@openedx/frontend-build",
231
+ "compilerOptions": {
232
+ "rootDir": ".",
233
+ "outDir": "dist"
234
+ },
235
+ "include": ["src/**/*"],
236
+ "exclude": ["dist", "node_modules"]
237
+ }
238
+ ```
239
+
240
+ ## Development
241
+
242
+ This project leverages the command line interface for webpack, jest,
243
+ eslint, and babel. Because of this, local development can be tricky. The
244
+ easiest way to do local development on this project is to either run
245
+ scripts inside the project in example or to test with an existing
246
+ project you can do the following:
247
+
248
+ 1. Delete the node\_modules directories in the host project:
249
+ `rm -rf node_modules/`
250
+ 2. Move frontend-build inside the host project and delete its node
251
+ modules folder
252
+ `mv ../frontend-build ./ && rm -rf frontend-build/node_modules`
253
+ 3. Install the development version of frontend-build
254
+ `npm i --save-dev @openedx/frontend-build@file:./frontend-build`.
255
+
256
+ ## License
257
+
258
+ The code in this repository is licensed under the AGPLv3 unless
259
+ otherwise noted.
260
+
261
+ Please see [LICENSE](LICENSE) for details.
262
+
263
+ ## Contributing
264
+
265
+ Contributions are very welcome. Please read [How To
266
+ Contribute](https://openedx.org/r/how-to-contribute) for details.
267
+
268
+ This project is currently accepting all types of contributions, bug
269
+ fixes, security fixes, maintenance work, or new features. However,
270
+ please make sure to have a discussion about your new feature idea with
271
+ the maintainers prior to beginning development to maximize the chances
272
+ of your change being accepted. You can start a conversation by creating
273
+ a new issue on this repo summarizing your idea.
274
+
275
+ ## Getting Help
276
+
277
+ If you\'re having trouble, we have discussion forums at
278
+ <https://discuss.openedx.org> where you can connect with others in the
279
+ community.
280
+
281
+ Our real-time conversations are on Slack. You can request a [Slack
282
+ invitation](https://openedx.org/slack), then join our [community Slack
283
+ workspace](https://openedx.slack.com/). Because this is a frontend
284
+ repository, the best place to discuss it would be in the [\#wg-frontend
285
+ channel](https://openedx.slack.com/archives/C04BM6YC7A6).
286
+
287
+ For anything non-trivial, the best path is to open an issue in this
288
+ repository with as many details about the issue you are facing as you
289
+ can provide.
290
+
291
+ <https://github.com/openedx/frontend-build/issues>
292
+
293
+ For more information about these options, see the [Getting
294
+ Help](https://openedx.org/community/connect) page.
295
+
296
+ ## Reporting Security Issues
297
+
298
+ Please do not report security issues in public. Please email
299
+ <security@openedx.org>.
300
+
301
+ ## Optimization
302
+
303
+ To increase optimization by reducing unused CSS, you can set
304
+ `USE_PURGECSS=true` in `.env` or as ENV var in the corresponding MFE.
305
+ However, note that doing this will increase build time by 30%. It\'s
306
+ thus not recommended to use this option during development. On the other
307
+ hand, enabling PurgeCSS will increase browser performance for the end
308
+ user by as much as 20% (as measured by
309
+ [lighthouse](https://developer.chrome.com/docs/lighthouse/overview/)).
310
+ Operators are encouraged to do so for production deployments.
311
+
312
+ For more information about optimizing MFEs, refer to the [issue
313
+ \#138](https://github.com/openedx/wg-frontend/issues/138) in the
314
+ wg-frontend repository.
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+
3
+ const chalk = require('chalk');
4
+
5
+ const presets = require('../lib/presets');
6
+
7
+ /**
8
+ * TLDR:
9
+ * - Find the command to be run in process.argv
10
+ * - Remove fedx-scripts in process.argv
11
+ * - Add a --config option to process.argv if one is missing
12
+ * - Execute the command's bin script by pulling it directly in with require()
13
+ *
14
+ * This file forwards cli commands by manipulating process.argv values and then
15
+ * directly requiring bin scripts from the specified packages (as opposed to
16
+ * attempting to run them from the aliases npm copies to the .bin folder upon
17
+ * install). This seems like a relatively safe thing to do since these file
18
+ * names are identical to their cli name and this method of requiring/executing
19
+ * them should behave the same as if run from the command line as usual.
20
+ */
21
+
22
+ function optionExists(keys) {
23
+ return process.argv.some((arg) => {
24
+ // eslint-disable-next-line no-plusplus
25
+ for (let i = 0; i < keys.length; i++) {
26
+ if (arg.startsWith(keys[i])) {
27
+ return true;
28
+ }
29
+ }
30
+ return false;
31
+ });
32
+ }
33
+
34
+ // Ensures that a config option already exists and if it does not adds a default
35
+ function ensureConfigOption(preset, keys = ['--config', '-c']) {
36
+ if (!optionExists(keys)) {
37
+ console.log(`Running with resolved config:\n${preset.resolvedFilepath}\n`);
38
+ process.argv.push(keys[0]);
39
+ process.argv.push(preset.resolvedFilepath);
40
+ }
41
+ }
42
+
43
+ // commandName is the third argument after node and fedx-scripts
44
+ const commandName = process.argv[2];
45
+
46
+ // remove fedx-scripts from process.argv to allow subcommands to read options properly
47
+ process.argv.splice(1, 1);
48
+
49
+ switch (commandName) {
50
+ case 'babel':
51
+ ensureConfigOption(presets.babel, ['--config-file']);
52
+ require('@babel/cli/bin/babel');
53
+ break;
54
+ case 'eslint':
55
+ ensureConfigOption(presets.eslint);
56
+ // eslint-disable-next-line import/extensions, import/no-extraneous-dependencies
57
+ require('.bin/eslint');
58
+ break;
59
+ case 'jest':
60
+ ensureConfigOption(presets.jest);
61
+ require('jest/bin/jest');
62
+ break;
63
+ case 'webpack':
64
+ ensureConfigOption(presets.webpack);
65
+ require('webpack/bin/webpack');
66
+ break;
67
+ case 'webpack-dev-server':
68
+ ensureConfigOption(presets.webpackDevServer);
69
+ require('webpack-dev-server/bin/webpack-dev-server');
70
+ break;
71
+ case 'formatjs': {
72
+ const commonArgs = [
73
+ '--format', 'node_modules/@openedx/frontend-build/lib/formatter.js',
74
+ '--ignore', 'src/**/*.json',
75
+ '--out-file', './temp/babel-plugin-formatjs/Default.messages.json',
76
+ '--', 'src/**/*.js*',
77
+ ];
78
+ process.argv = process.argv.concat(commonArgs);
79
+ ensureConfigOption(presets.formatjs);
80
+ require('@formatjs/cli/bin/formatjs');
81
+ break;
82
+ }
83
+ case 'serve':
84
+ require('../lib/scripts/serve');
85
+ break;
86
+ default:
87
+ console.log(chalk.red(`[ERROR] fedx-scripts: The command ${chalk.bold.red(commandName)} is unsupported.`));
88
+ }
@@ -0,0 +1,46 @@
1
+ const { babel } = require('../lib/presets');
2
+
3
+ module.exports = {
4
+ extends: '@edx/eslint-config',
5
+ plugins: ['@typescript-eslint'],
6
+ parser: '@typescript-eslint/parser',
7
+ parserOptions: {
8
+ requireConfigFile: true,
9
+ babelOptions: {
10
+ configFile: babel.resolvedFilepath || babel.defaultFilepath,
11
+ },
12
+ },
13
+ rules: {
14
+ 'import/no-extraneous-dependencies': [
15
+ 'error',
16
+ {
17
+ devDependencies: [
18
+ '**/*.config.*',
19
+ '**/*.test.*',
20
+ '**/setupTest.js',
21
+ ],
22
+ },
23
+ ],
24
+ 'import/no-unresolved': [
25
+ 'error',
26
+ {
27
+ ignore: [
28
+ 'env.config',
29
+ ],
30
+ },
31
+ ],
32
+ // https://github.com/evcohen/eslint-plugin-jsx-a11y/issues/340#issuecomment-338424908
33
+ 'jsx-a11y/anchor-is-valid': ['error', {
34
+ components: ['Link'],
35
+ specialLink: ['to'],
36
+ }],
37
+ 'import/no-import-module-export': 'off',
38
+ 'react/function-component-definition': [2, { namedComponents: 'arrow-function' }],
39
+ },
40
+ globals: {
41
+ newrelic: false,
42
+ },
43
+ ignorePatterns: [
44
+ 'module.config.js',
45
+ ],
46
+ };
@@ -0,0 +1,30 @@
1
+ module.exports = {
2
+ presets: [
3
+ [
4
+ '@babel/preset-env',
5
+ {
6
+ modules: false,
7
+ },
8
+ ],
9
+ '@babel/preset-react',
10
+ ],
11
+ plugins: [
12
+ '@babel/plugin-proposal-object-rest-spread',
13
+ '@babel/plugin-proposal-class-properties',
14
+ '@babel/plugin-syntax-dynamic-import',
15
+ ],
16
+ env: {
17
+ i18n: {
18
+ plugins: [
19
+ [
20
+ 'formatjs',
21
+ ],
22
+ ],
23
+ },
24
+ test: {
25
+ presets: [
26
+ '@babel/preset-env',
27
+ ],
28
+ },
29
+ },
30
+ };
@@ -0,0 +1,5 @@
1
+ const config = require('./babel.config');
2
+
3
+ config.presets.push('@babel/preset-typescript');
4
+
5
+ module.exports = config;
@@ -0,0 +1,41 @@
1
+ module.exports = {
2
+ presets: [
3
+ '@babel/preset-env',
4
+ [
5
+ '@babel/preset-react', {
6
+ runtime: 'automatic',
7
+ },
8
+ ],
9
+ ],
10
+ plugins: [
11
+ '@babel/plugin-proposal-object-rest-spread',
12
+ '@babel/plugin-proposal-class-properties',
13
+ '@babel/plugin-syntax-dynamic-import',
14
+ [
15
+ 'transform-imports',
16
+ {
17
+ '@fortawesome/free-brands-svg-icons': {
18
+ transform: '@fortawesome/free-brands-svg-icons/${member}',
19
+ skipDefaultConversion: true,
20
+ },
21
+ '@fortawesome/free-regular-svg-icons': {
22
+ transform: '@fortawesome/free-regular-svg-icons/${member}',
23
+ skipDefaultConversion: true,
24
+ },
25
+ '@fortawesome/free-solid-svg-icons': {
26
+ transform: '@fortawesome/free-solid-svg-icons/${member}',
27
+ skipDefaultConversion: true,
28
+ },
29
+ },
30
+ ],
31
+ ],
32
+ env: {
33
+ i18n: {
34
+ plugins: [
35
+ [
36
+ 'formatjs',
37
+ ],
38
+ ],
39
+ },
40
+ },
41
+ };
@@ -0,0 +1,67 @@
1
+ const path = require('path');
2
+ const fs = require('fs');
3
+
4
+ /*
5
+ This function reads in a 'module.config.js' file if it exists and uses its contents to define
6
+ a set of webpack resolve.alias aliases for doing local development of application dependencies.
7
+ It reads the package.json file of the dependency to determine if it has any peer dependencies, and
8
+ then forces those peer dependencies to be resolved with the application's version. Primarily, this
9
+ is useful for making sure there's only one version of those dependencies loaded at once, which is a
10
+ problem with both react and react-intl.
11
+
12
+ The module.config.js file should have the form:
13
+
14
+ {
15
+ localModules: [
16
+ { moduleName: 'nameOfPackage', dir: '../path/to/repo', dist: '/path/to/dist/in/repo' },
17
+ ... others...
18
+ ],
19
+ }
20
+
21
+ Some working examples, as of the time of this writing:
22
+
23
+ { moduleName: '@openedx/paragon/scss', dir: '../paragon', dist: 'scss' }
24
+ { moduleName: '@openedx/paragon', dir: '../paragon', dist: 'dist' }
25
+ { moduleName: '@edx/frontend-platform', dir: '../frontend-platform', dist: 'dist' }
26
+
27
+ */
28
+ function getLocalAliases() {
29
+ const aliases = {};
30
+
31
+ try {
32
+ const moduleConfigPath = path.resolve(process.cwd(), 'module.config.js');
33
+ if (!fs.existsSync(moduleConfigPath)) {
34
+ console.log('No local module configuration file found. This is fine.');
35
+ return aliases;
36
+ }
37
+ // eslint-disable-next-line import/no-dynamic-require, global-require
38
+ const { localModules } = require(moduleConfigPath);
39
+
40
+ let allPeerDependencies = [];
41
+ const excludedPeerPackages = [];
42
+ if (localModules.length > 0) {
43
+ console.info('Resolving modules from local directories via module.config.js.');
44
+ }
45
+ localModules.forEach(({ moduleName, dir, dist = '' }) => {
46
+ console.info(`Using local version of ${moduleName} from ${dir}/${dist}.`);
47
+ // eslint-disable-next-line import/no-dynamic-require, global-require
48
+ const { peerDependencies = {}, name } = require(path.resolve(process.cwd(), dir, 'package.json'));
49
+ allPeerDependencies = allPeerDependencies.concat(Object.keys(peerDependencies));
50
+ aliases[moduleName] = path.resolve(process.cwd(), dir, dist);
51
+ excludedPeerPackages.push(name);
52
+ });
53
+
54
+ allPeerDependencies = allPeerDependencies.filter((dep) => !excludedPeerPackages.includes(dep));
55
+
56
+ allPeerDependencies.forEach((dep) => {
57
+ aliases[dep] = path.resolve(process.cwd(), 'node_modules', dep);
58
+ });
59
+ } catch (e) {
60
+ console.error(e);
61
+ console.error('Error in module.config.js parsing. module.config.js will be ignored.');
62
+ return {};
63
+ }
64
+ return aliases;
65
+ }
66
+
67
+ module.exports = getLocalAliases;
@@ -0,0 +1,12 @@
1
+ module.exports = {
2
+ // DO NOT PUT ANY CONFIGURATION IN THIS FILE.
3
+
4
+ // The existence of this file is a technical detail of the mechanism used to implement
5
+ // env.config.js files for jest.
6
+
7
+ // This file is used as a fallback to prevent build errors if an env.config.js file has not been
8
+ // defined in a consuming application. If we could inline an empty object instead of needing a
9
+ // file to reference, that'd be clearer, but doesn't seem to be an option.
10
+
11
+ // This is NOT an appropriate place to put actual configuration values for tests.
12
+ };
@@ -0,0 +1 @@
1
+ module.exports = 'test-file-stub';
@@ -0,0 +1,10 @@
1
+ const path = require('path');
2
+ const fs = require('fs');
3
+ const dotenv = require('dotenv');
4
+ require('babel-polyfill');
5
+
6
+ const testEnvFile = path.resolve(process.cwd(), '.env.test');
7
+
8
+ if (fs.existsSync(testEnvFile)) {
9
+ dotenv.config({ path: testEnvFile });
10
+ }
@@ -0,0 +1,4 @@
1
+ export const ReactComponent = 'IconMock';
2
+
3
+ const mock = 'icon/mock/path';
4
+ export default mock;
@@ -0,0 +1,45 @@
1
+ const path = require('path');
2
+ const fs = require('fs');
3
+ const { jsWithTs: tsjPreset } = require('ts-jest/presets');
4
+
5
+ const presets = require('../lib/presets');
6
+
7
+ let envConfigPath = path.resolve(__dirname, './jest/fallback.env.config.js');
8
+ const appEnvConfigPath = path.resolve(process.cwd(), './env.config.js');
9
+
10
+ if (fs.existsSync(appEnvConfigPath)) {
11
+ envConfigPath = appEnvConfigPath;
12
+ }
13
+
14
+ module.exports = {
15
+ testURL: 'http://localhost/',
16
+ setupFiles: [
17
+ path.resolve(__dirname, 'jest/setupTest.js'),
18
+ ],
19
+ rootDir: process.cwd(),
20
+ moduleNameMapper: {
21
+ '\\.svg': path.resolve(__dirname, 'jest/svgrMock.js'),
22
+ '\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': path.resolve(__dirname, 'jest/fileMock.js'),
23
+ '\\.(css|scss)$': 'identity-obj-proxy',
24
+ 'env.config': envConfigPath,
25
+ },
26
+ collectCoverageFrom: [
27
+ 'src/**/*.{js,jsx}',
28
+ ],
29
+ coveragePathIgnorePatterns: [
30
+ '/node_modules/',
31
+ 'setupTest.js',
32
+ ],
33
+ transformIgnorePatterns: [
34
+ '/node_modules/(?!@(open)?edx)',
35
+ ],
36
+ transform: {
37
+ '^.+\\.jsx?$': [
38
+ 'babel-jest',
39
+ {
40
+ configFile: presets.babel.resolvedFilepath,
41
+ },
42
+ ],
43
+ ...tsjPreset.transform,
44
+ },
45
+ };