Installing default openedx header/footer frontend components breaks Redwood MFE build

I’m planning to customize the MFE header and footer on a Redwood installation, but as a preliminary step i’m only trying to get the tutor-mfe image build procedure to work, using the default frontend-component-header and frontend-component-footer repos.

This is my tutor plugin, which appears to be working as expected. running tutor images build mfe results in this Dockerfile being generated, which also appears to be correct.

For the avoidance of any doubt, the substance of the tutor patches follows this pattern which i took from the tutor-mfe README page:

from tutor import hooks

hooks.Filters.ENV_PATCHES.add_item(
    (
        "mfe-dockerfile-post-npm-install-learning",
        """
RUN npm install '@edx/frontend-component-header@git+https://github.com/openedx/frontend-component-header.git'
RUN npm install '@edx/frontend-component-footer@git+https://github.com/openedx/frontend-component-footer.git'
"""
    )
)

However, the build fails with the following console output.

The substantive portion of the console output is as follows:

=> ERROR [learning-prod 1/1] RUN npm run build                                                                                                                                                                                146.0s
------                                                                                                                                                                                                                                
 > importing cache manifest from 090511222473.dkr.ecr.us-east-2.amazonaws.com/stepwisemath/openedx-mfe-v18:18.1.3-202410031826-cache:                                                                                                 
------                                                                                                                                                                                                                                
------                                                                                                                                                                                                                                
 > [learning-prod 1/1] RUN npm run build:                                                                                                                                                                                             
0.540                                                                                                                                                                                                                                 
0.540 > @edx/frontend-app-learning@1.0.0-semantically-released build
0.540 > fedx-scripts webpack
0.540 
0.598 Running with resolved config:
0.598 /openedx/app/webpack.prod.config.js
0.598 
1.551 Browserslist: caniuse-lite is outdated. Please run:
1.551   npx update-browserslist-db@latest
1.551   Why you should do it regularly: https://github.com/browserslist/update-db#readme
145.0 Error parsing bundle asset "/openedx/app/dist/263.42ded56b1601a41b230c.js": no such file
145.0 Error parsing bundle asset "/openedx/app/dist/app.e234fd2d5cbd1b64e9d6.js": no such file
145.0 Error parsing bundle asset "/openedx/app/dist/700.527abebe778e1b7cf0ce.js": no such file
145.0 Error parsing bundle asset "/openedx/app/dist/35.3fd162fd31dcc6663d4b.js": no such file
145.0 Error parsing bundle asset "/openedx/app/dist/runtime.302438b30390ec69b1d3.js": no such file
145.0 Error parsing bundle asset "/openedx/app/dist/106.474fa2bbc3e6fa7afd99.js": no such file
145.0 Error parsing bundle asset "/openedx/app/dist/210.fb586582bddc7eea8376.js": no such file
145.0 Error parsing bundle asset "/openedx/app/dist/974.558db8619526b7b79d0f.js": no such file
145.0 Error parsing bundle asset "/openedx/app/dist/715.1c72fe5841ccb4b1b2b8.js": no such file
145.0 Error parsing bundle asset "/openedx/app/dist/437.0222582e86be5b38c1d5.js": no such file
145.0 Error parsing bundle asset "/openedx/app/dist/724.25aa06ea2b6b272a1efe.js": no such file
145.0 Error parsing bundle asset "/openedx/app/dist/901.202fb5acec0d67427a89.js": no such file
145.0 Error parsing bundle asset "/openedx/app/dist/28.bc7c2289d98e72d5a48c.js": no such file
145.0 Error parsing bundle asset "/openedx/app/dist/443.40af5685c505b9be8606.js": no such file
145.0 
145.0 No bundles were parsed. Analyzer will show only original module sizes from stats file.
145.0 
145.2 Webpack Bundle Analyzer saved report to /openedx/app/dist/report.html
145.7 assets by status 8.59 MiB [cached] 34 assets
145.7 Entrypoint app = runtime.302438b30390ec69b1d3.js 263.42ded56b1601a41b230c.js app.e234fd2d5cbd1b64e9d6.css app.e234fd2d5cbd1b64e9d6.js 21 auxiliary assets
145.7 orphan modules 7.71 MiB [orphan] 3597 modules
145.7 runtime modules 8.93 KiB 16 modules
145.7 cacheable modules 11.9 MiB (javascript) 498 KiB (css/mini-extract)
145.7   javascript modules 11.8 MiB
145.7     modules by path ./node_modules/ 9.48 MiB 1222 modules
145.7     modules by path ./src/ 2.31 MiB 29 modules
145.7     + 2 modules
145.7   json modules 115 KiB
145.7     modules by path ./node_modules/i18n-iso-countries/ 63.9 KiB 14 modules
145.7     modules by path ./node_modules/@cospired/i18n-iso-languages/ 20.2 KiB 6 modules
145.7     modules by path ./node_modules/cheerio/ 31.2 KiB 6 modules
145.7   css modules 498 KiB
145.7     modules by path ./node_modules/ 3.52 KiB 7 modules
145.7     modules by path ./src/ 495 KiB 2 modules
145.7 
145.7 ERROR in ./node_modules/@openedx/frontend-slot-footer/dist/FooterSlot.js 9:54-95
145.7 Module not found: Error: Can't resolve '@edx/frontend-component-footer' in '/openedx/app/node_modules/@openedx/frontend-slot-footer/dist'
145.7  @ ./node_modules/@openedx/frontend-slot-footer/dist/index.js 7:41-64
145.7  @ ./src/generic/CourseAccessErrorPage.jsx 11:0-55 41:28-38 60:26-36
145.7  @ ./src/index.jsx 28:0-68 59:44-65
145.7 
145.7 ERROR in ./src/course-home/goal-unsubscribe/GoalUnsubscribe.jsx 5:0-74
145.7 Module not found: Error: Can't resolve '@edx/frontend-component-header' in '/openedx/app/src/course-home/goal-unsubscribe'
145.7  @ ./src/course-home/goal-unsubscribe/index.jsx 1:0-48 2:15-30
145.7  @ ./src/index.jsx 19:0-61 49:44-59
145.7 
145.7 ERROR in ./src/generic/CourseAccessErrorPage.jsx 7:0-74
145.7 Module not found: Error: Can't resolve '@edx/frontend-component-header' in '/openedx/app/src/generic'
145.7  @ ./src/index.jsx 28:0-68 59:44-65
145.7 
145.7 ERROR in ./src/tab-page/TabPage.jsx 15:0-74
145.7 Module not found: Error: Can't resolve '@edx/frontend-component-header' in '/openedx/app/src/tab-page'
145.7  @ ./src/tab-page/index.js 2:0-47 2:0-47
145.7  @ ./src/index.jsx 21:0-42 64:44-56 74:44-56 84:44-56 94:44-56 104:44-56 115:44-56
145.7 
145.7 ERROR in ./src/index.scss
145.7 Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
145.7 ModuleBuildError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
145.7 Can't find stylesheet to import.
145.7   ╷
145.7 6 │ @import "~@edx/frontend-component-footer/dist/footer";
145.7   │         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
145.7   ╵
145.7   src/index.scss 6:9  root stylesheet
145.7     at processResult (/openedx/app/node_modules/webpack/lib/NormalModule.js:764:19)
145.7     at /openedx/app/node_modules/webpack/lib/NormalModule.js:866:5
145.7     at /openedx/app/node_modules/loader-runner/lib/LoaderRunner.js:400:11
145.7     at /openedx/app/node_modules/loader-runner/lib/LoaderRunner.js:252:18
145.7     at context.callback (/openedx/app/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
145.7     at Object.loader (/openedx/app/node_modules/sass-loader/dist/index.js:63:5)
145.7  @ ./src/index.jsx 13:0-22
145.7 
145.7 1 ERROR in child compilations (Use 'stats.children: true' resp. '--stats-children' for more details)
145.7 
145.7 4 errors have detailed information that is not shown.
145.7 Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it.
145.7 
145.7 webpack 5.89.0 compiled with 6 errors in 139130 ms
------
Dockerfile:657
--------------------
 655 |     FROM learning-common AS learning-prod
 656 |     ENV NODE_ENV=production
 657 | >>> RUN npm run build
 658 |     
 659 |     
--------------------
ERROR: failed to solve: process "/bin/sh -c npm run build" did not complete successfully: exit code: 1
Error: Command failed with status 1: docker buildx build --tag=090511222473.dkr.ecr.us-east-2.amazonaws.com/stepwisemath/openedx-mfe-v18:18.1.3-202410031826 --output=type=docker --cache-from=type=registry,ref=090511222473.dkr.ecr.us-east-2.amazonaws.com/stepwisemath/openedx-mfe-v18:18.1.3-202410031826-cache /home/ubuntu/.local/share/tutor/env/plugins/mfe/build/mfe

Can anyone explain what I’m doing wrong?

Hello lpm0073Lawrence McDaniel

To work with frontend-componet-header and frontend-componet-footer
You must first clone the frontend-component-XXXX repository:

Then from the folder:

frontend-component-XXXX - npm install
frontend-component-header - npm run build

Change in the package.json for example of the frontend-app-learning (only in the local instance DO NOT commit this file)

@edx/frontend-component-header”: “file:…/frontend-component-header”,

From the folder:

frontend-app-learning - npm install ‘@edx/frontend-component-header@…/frontend-component-header’

And every time you make a change in the Header or Footer, you must do the npm build of it and install it in the Learning or wherever you are testing it

Thank you very much @Juan-Carlos, your guidance above was helpful. Confirming that cloning the forked header/footer repos inside the Docker container resolved the build error I was getting. On an aside however, this leaves me wondering why this is not necessary for the ‘brand-openedx’ package that I’m also including in the same build. weird.

As part of the same preliminary test, I’m using this fork – StepwiseMath/frontend-component-header – which contains a single modification to the Learning MFE page title which is supposed to look like the following


where the existence of the string “FORKED:” would confirm that the modified header was actually in use on the page. Sadly, this is not the case. I can see evidence that the forked header repo was indeed included in the build workflow. For example, this snippet of console output is of the frontend-component-footer installation.

However, I do not find the string ‘FORKED:’ anywhere inside the generated React build artifacts when searching inside the deployed MFE container itself.

My revised patch, patches/mfe-dockerfile-post-npm-install-learning, now contains the following:

RUN git clone --branch open-release/redwood.master https://github.com/StepwiseMath/frontend-component-header.git ./frontend-component-header
RUN git clone --branch open-release/redwood.master https://github.com/StepwiseMath/frontend-component-footer.git ./frontend-component-footer

RUN cd ./frontend-component-header && npm install
RUN cd ./frontend-component-footer && npm install

I don’t know if this would help you, but you have to mount the MFE where you installed the Header and Footer, to see the changes locally

tutor mounts add /(local path)/frontend-app-XXXX

tutor config save

and check the file ‘docker-compose.yml’ to see if it is well assembled.

Thanks @Juan-Carlos. I’m working on a production build-deploy, not a dev stack. Do you by any chance have a working example of a modified mfe build workflow that i could review?

I don’t actually work in production, those tasks are done by my boss, but I’ll ask him to see if he can give you a hand.

1 Like

After more research and experimentation I’ve gotten very close to getting this work. my updated commands, which I’ve since learned will only work when run from the patch mfe-dockerfile-post-npm-install are:

RUN git clone --branch open-release/redwood.master https://github.com/StepwiseMath/frontend-component-header.git /openedx/app/frontend-component-header
RUN git clone --branch open-release/redwood.master https://github.com/StepwiseMath/frontend-component-footer.git /openedx/app/frontend-component-footer

# Install the npm packages from the local files
RUN cd /openedx/app/frontend-component-header && npm install
RUN cd /openedx/app/frontend-component-footer && npm install

# Build the npm packages from the local files
RUN cd /openedx/app/frontend-component-header && npm run build
RUN cd /openedx/app/frontend-component-footer && npm run build

RUN npm install --save '@edx/frontend-component-header@/openedx/app/frontend-component-header-edx'
RUN npm install --save '@edx/frontend-component-footer@/openedx/app/frontend-component-footer-edx'

These result in the final straggling console errors:

102.8 Webpack Bundle Analyzer saved report to /openedx/app/dist/report.html
103.3 assets by status 4.32 MiB [cached] 8 assets
103.3 Entrypoint app = runtime.7c52a68126382c0948a6.js 62.5f3f6153775d6ce15203.css 62.5f3f6153775d6ce15203.js app.847ac3e8a14b26740118.css app.847ac3e8a14b26740118.js 7 auxiliary assets
103.3 orphan modules 6.32 MiB [orphan] 3269 modules
103.3 runtime modules 4.88 KiB 11 modules
103.3 cacheable modules 7.66 MiB (javascript) 97.9 KiB (css/mini-extract)
103.3   javascript modules 7.58 MiB 930 modules
103.3   json modules 84.1 KiB
103.3     modules by path ./node_modules/i18n-iso-countries/ 63.9 KiB 14 modules
103.3     modules by path ./node_modules/@cospired/i18n-iso-languages/ 20.2 KiB
103.3       ./node_modules/@cospired/i18n-iso-languages/langs/en.json 2.79 KiB [built] [code generated]
103.3       + 5 modules
103.3   css modules 97.9 KiB
103.3     modules by path ./src/ 440 bytes 4 modules
103.3     modules by path ./node_modules/ 97.5 KiB
103.3       modules by path ./node_modules/tinymce/skins/ui/oxide/*.css 96.2 KiB 2 modules
103.3       + 2 modules
103.3 
103.3 ERROR in ./src/components/page-container/PageContainer.jsx 4:0-74
103.3 Module not found: Error: Can't resolve '@edx/frontend-component-header' in '/openedx/app/src/components/page-container'
103.3  @ ./src/index.jsx 11:0-70 25:38-51
103.3 
103.3 ERROR in ./src/index.scss
103.3 Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
103.3 ModuleBuildError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
103.3 Can't find stylesheet to import.
103.3   ╷
103.3 6 │ @import "~@edx/frontend-component-header/dist/index";
103.3   │         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
103.3   ╵
103.3   src/index.scss 6:9  root stylesheet
103.3     at processResult (/openedx/app/node_modules/webpack/lib/NormalModule.js:764:19)
103.3     at /openedx/app/node_modules/webpack/lib/NormalModule.js:866:5
103.3     at /openedx/app/node_modules/loader-runner/lib/LoaderRunner.js:400:11
103.3     at /openedx/app/node_modules/loader-runner/lib/LoaderRunner.js:252:18
103.3     at context.callback (/openedx/app/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
103.3     at Object.loader (/openedx/app/node_modules/sass-loader/dist/index.js:63:5)
103.3  @ ./src/index.jsx 9:0-22
103.3 
103.3 ERROR in ./node_modules/@openedx/frontend-slot-footer/dist/FooterSlot.js 9:54-95
103.3 Module not found: Error: Can't resolve '@edx/frontend-component-footer' in '/openedx/app/node_modules/@openedx/frontend-slot-footer/dist'
103.3  @ ./node_modules/@openedx/frontend-slot-footer/dist/index.js 7:41-64
103.3  @ ./src/components/page-container/PageContainer.jsx 5:0-55 81:30-40
103.3  @ ./src/index.jsx 11:0-70 25:38-51
103.3 
103.3 1 ERROR in child compilations (Use 'stats.children: true' resp. '--stats-children' for more details)
103.3 
103.3 2 errors have detailed information that is not shown.
103.3 Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it.
103.3 
103.3 webpack 5.89.0 compiled with 4 errors in 96208 ms

These respectively are generated by the MFE’s page-container, mini-css-extract-plugin, and frontend-slot-footer, and each of these seems to an import error that’s raised when attempting to import a style sheet.

Hi @lpm0073 ,
I mostly made MFEs header/footer changes using tutor dev. You have to follow similar steps for header and footer if you are using tutor dev. The module.config.js file will be like (You have to set “dist” correctly):

module.exports = {
    localModules: [
      { moduleName: '@edx/frontend-component-header', dir: '../frontend-component-header', dist: 'src' },
      { moduleName: '@edx/frontend-component-footer', dir: '../frontend-component-footer'  },
      { moduleName: '@edx/brand', dir: '../brand-openedx'  },
    ],
  };

For production, I publish ‘header’ and ‘footer’ package on npm and it like that:


hooks.Filters.ENV_PATCHES.add_items(
        (
            "mfe-dockerfile-post-npm-install-learning",
            """
RUN npm install '@edx/brand@npm:@edly-io/indigo-brand-openedx'
RUN npm install '@edx/frontend-component-header@npm:@edly-io/indigo-frontend-component-header'
RUN npm install @edly-io/indigo-frontend-component-footer
""",
        ),
)

I think that the problem is here:

RUN cd /openedx/app/frontend-component-footer && npm run build

when this runs, you have to cd .. to get back to the app folder. Currently, it seems like npm install --save '@edx/frontend-component-header@/openedx/app/frontend-component-header-edx' commands are executed in /openedx/app/frontend-component-footer folder.

Thank you very much for responding @hinakhadim. That is not how Docker interprets and runs its commands. To the contrary, each RUN command is treated like a separate bash command that begins its execution in the WORKDIR of the Dockerfile. Thus, explicitly changing directories back to WORKDIR is a benign, no-op.

Zooming out, I was able to get this to work. Summarizing my experience however, installing from code presents a variety of technical challenges, mostly related to how one should go about linking the package folder to the consuming npm environment. I found this approach to be alarmingly unstable, and so in my case I abandoned this approach in favor of publishing my package to npmjs. Thus, my code now looks nearly identical to yours.

1 Like