{"id":20037771,"url":"https://github.com/openedx/frontend-build","last_synced_at":"2025-04-04T15:06:14.545Z","repository":{"id":37396342,"uuid":"210365233","full_name":"openedx/frontend-build","owner":"openedx","description":"Common build scripts and tooling for Open edX micro-frontends.","archived":false,"fork":false,"pushed_at":"2025-03-11T22:58:51.000Z","size":16627,"stargazers_count":18,"open_issues_count":32,"forks_count":35,"subscribers_count":51,"default_branch":"master","last_synced_at":"2025-03-21T18:03:11.843Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openedx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-23T13:41:45.000Z","updated_at":"2025-03-04T21:50:33.000Z","dependencies_parsed_at":"2022-07-08T16:47:11.577Z","dependency_job_id":"5c1a7acb-d32c-48b3-bd6a-4d35da9cb70e","html_url":"https://github.com/openedx/frontend-build","commit_stats":{"total_commits":274,"total_committers":40,"mean_commits":6.85,"dds":0.6204379562043796,"last_synced_commit":"d31d8d457dd539fb3b3de75499f5af53e805268e"},"previous_names":[],"tags_count":380,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openedx%2Ffrontend-build","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openedx%2Ffrontend-build/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openedx%2Ffrontend-build/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openedx%2Ffrontend-build/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openedx","download_url":"https://codeload.github.com/openedx/frontend-build/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247198448,"owners_count":20900079,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T10:21:59.062Z","updated_at":"2025-04-04T15:06:14.524Z","avatar_url":"https://github.com/openedx.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# frontend-build\n\n[![Build\nStatus](https://api.travis-ci.com/edx/frontend-build.svg?branch=master)](https://travis-ci.com/edx/frontend-build)\n![npm\\_version](https://img.shields.io/npm/v/@openedx/frontend-build.svg)\n[![Codecov](https://img.shields.io/codecov/c/github/edx/frontend-build)](https://codecov.io/gh/edx/frontend-build)\n[![license](https://img.shields.io/npm/l/@openedx/frontend-build.svg)](https://github.com/edx-unsupported/frontend-base/blob/master/LICENSE)\n\n## Purpose\n\nThe purpose of this package is to provide a common sense foundation and\nsetup for frontend projects including:\n\n-   linting (eslint)\n-   testing (jest)\n-   development server (webpack-dev-server)\n-   build (webpack)\n\nThis package can serve as a single dev dependency replacing a large\nnumber of dev and build dependencies. It aims to provide common sense\ndefaults that should be good for most edX projects out of the box, but\ncan extended or overridden where needed.\n\n## Cloning and Startup\n\n``` {.}\n1. Clone your new repo:\n\n  ``git clone https://github.com/openedx/frontend-build.git``\n\n2. Use node v18.x.\n\n  The current version of the micro-frontend build scripts support node 18.\n  Using other major versions of node *may* work, but this is unsupported.  For\n  convenience, this repository includes an .nvmrc file to help in setting the\n  correct node version via `nvm \u003chttps://github.com/nvm-sh/nvm\u003e`_.\n\n3. Install npm dependencies:\n\n  ``cd frontend-build \u0026\u0026 npm ci``\n```\n\n## Usage\n\nCLI commands are structured: `fedx-scripts \u003ctargetScript\u003e \u003coptions\u003e`.\nOptions are passed on to the target script, so refer to each target\nscript\\'s CLI documentation to learn what options are available. Example\npackage.json:\n\n    {\n       \"scripts\": {\n          \"build\": \"fedx-scripts webpack\",\n          \"i18n_extract\": \"fedx-scripts formatjs extract\",\n          \"lint\": \"fedx-scripts eslint --ext .jsx,.js .\",\n          \"precommit\": \"npm run lint\",\n          \"snapshot\": \"fedx-scripts jest --updateSnapshot\",\n          \"start\": \"fedx-scripts webpack-dev-server --progress\",\n          \"test\": \"fedx-scripts jest --coverage --passWithNoTests\",\n          \"serve\": \"fedx-scripts serve\"\n       },\n       \"dependencies\": {\n          ...\n       },\n       \"devDependencies\": {\n          \"@openedx/frontend-build\": \"1.0.0\"\n       }\n    }\n\n## Extending or Overriding Config Presets\n\nThis package contains a set of configuration presets:\n\n-   webpack-prod (or webpack)\n-   webpack-dev (or webpack-dev-server)\n-   webpack-dev-stage (for running development apps against stage apis)\n-   babel\n-   babel-preserve-modules\n-   jest\n-   eslint\n\nIf you need to extend or modify a configuration you can add your own\nconfiguration files, either by extending frontend-build\\'s configuration\nfiles or supplying your own wholesale.\n\nMethod 1: Extend base config (babel.config.js):\n\n    const { createConfig } = require('@openedx/frontend-build');\n    module.exports = createConfig('babel', {\n       /* option overrides or extensions */\n    });\n\nMethod 2: Custom manipulations (babel.config.js):\n\n    const { getBaseConfig } = require('@openedx/frontend-build');\n    const config = getBaseConfig('babel');\n\n    /* Custom config manipulations */\n\n    module.exports = config;\n\nFrontend build will look in the following locations for configuration\nfiles in your project.\n\n-   eslint: `\u003cproject_root\u003e/.eslintrc.js`\n-   jest: `\u003cproject_root\u003e/jest.config.js`\n-   babel: `\u003cproject_root\u003e/babel.config.js`\n-   webpack-prod: `\u003cproject_root\u003e/webpack.prod.config.js`\n-   webpack-dev-server: `\u003cproject_root\u003e/webpack.dev.config.js`\n\nYou may specify custom config file locations via the command line if you\nprefer a different location. Example package.json:\n\n    {\n       \"scripts\": {\n          \"build\": \"fedx-scripts webpack --config ./config/webpack.config.js\",\n          \"start:stage\": \"fedx-scripts webpack-dev-server --config webpack.dev-stage.config.js\",\n          ...\n       }\n    }\n\nNote, specifying a custom config location for babel may cause issues\nwith other tools in frontend-build. eslint, jest, webpack, and\nwebpack-dev-server configuration presets rely upon the babel config and\nresolve the location of the config file according to the default\nlocations described above. If you need to move the babel config file to\na custom location, you may also need to customize references to its\nlocation in other configuration files. Please reach out to the FedX team\nif you need to do this and are running into problems.\n\n## Local module configuration for Webpack\n\n\nThe development webpack configuration allows engineers to create a\n\\\"module.config.js\\\" file containing local module overrides. This means\nthat if you\\'re developing a new feature in a shared library\n(\\@edx/frontend-platform, \\@openedx/paragon, etc.), you can add the local\nlocation of that repository to your module.config.js file and the\nwebpack build for your application will automatically pick it up and use\nit, rather than its node\\_modules version of the file.\n\n**NOTE: This module.config.js file should be added to your**\n[.gitignore]{.title-ref}.\n\nAn example module.config.js file looks like the following. You can copy\nthis into your application to use local versions of paragon and\nfrontend-platform:\n\n    module.exports = {\n      /*\n      Modules you want to use from local source code.  Adding a module here means that when this app\n      runs its build, it'll resolve the source from peer directories of this app.\n\n      moduleName: the name you use to import code from the module.\n      dir: The relative path to the module's source code.\n      dist: The sub-directory of the source code where it puts its build artifact.  Often \"dist\".\n      */\n      localModules: [\n        { moduleName: '@edx/brand', dir: '../src/brand-openedx' }, // replace with your brand checkout\n        { moduleName: '@openedx/paragon/scss/core', dir: '../src/paragon', dist: 'scss/core' },\n        { moduleName: '@openedx/paragon/icons', dir: '../src/paragon', dist: 'icons' },\n        { moduleName: '@openedx/paragon', dir: '../src/paragon', dist: 'dist' },\n        { moduleName: '@edx/frontend-platform', dir: '../src/frontend-platform', dist: 'dist' },\n      ],\n    };\n\n## Steps\n\n1.  Copy the `module.config.js` into your frontend app repository,\n    modifying it as necessary.\n2.  Run `npm install \u0026\u0026 npm run build` within any shared NPM package you\n    want to use locally.\n3.  Restart your app.\n\n## Notes\n\n-   The \\\"dir\\\" and \\\"dist\\\" keys give you granular control over the\n    shape of your repository\\'s distribution. Paragon, for instance,\n    needs two separate entries to pick up both JS and SCSS imports.\n-   The directory location `../src` (relative to the root of your\n    frontend app repository) is recommended for shared NPM package\n    repositories, since it will work whether or not you are running your\n    frontend via devstack. If you are *not* running your frontend via\n    devstack, then you can place your shared libraries anywhere in your\n    file system, updating the \\\"dir\\\" key accordingly. To learn more,\n    see [this devstack ADR on local\n    packages](https://github.com/openedx/devstack/tree/master/docs/decisions/0005-frontend-package-mounts.rst).\n-   This mechanism uses Webpack resolve aliases, as documented here:\n    \u003chttps://webpack.js.org/configuration/resolve/#resolvealias\u003e\n\n## Override default .env.development environment variables with .env.private\n\nIn some situations, you may want to override development environment\nvariables defined in .env.development with private environment variables\nthat should never be checked into a repository. For example, a\n.env.development file may contain secrets for a third-party service\n(e.g., Algolia) that you\\'d like to use during development but want to\nensure these secrets are not checked into Git.\n\nYou may create a [.env.private]{.title-ref} with any overrides of the\nenvironment settings configured in [.env.development]{.title-ref}.\n\n**Note: .env.private should be added to your project\\'s .gitignore so it\ndoes not get checked in.**\n\n## Serving a production Webpack build locally\n\nIn some scenarios, you may want to run a production Webpack build\nlocally. To serve a production build locally:\n\n1.  Create an `env.config.js` file containing the configuration for\n    local development, with the exception of `NODE_ENV='production'`.\n2.  Run `npm run build` to build the production assets. The output\n    assets will rely on the local development configuration specified in\n    the prior step.\n3.  Add an NPM script `serve` to your application\\'s `package.json`\n    (i.e., `\"serve\": \"fedx-scripts serve\"`).\n4.  Run `npm run serve` to serve your production build assets. It will\n    attempt to run the build on the same port specified in the\n    `env.config.js` file.\n\n## Local module configuration for TypeScript\n\n#. Create file in repository `tsconfig.json`, with a clause `\"extends\": \"@openedx/frontend-build\"`\n#. Set \"rootDir\" to the root of the source code folders\n#. Set \"include\" to wildcard patterns specifying the subdirectories/files under rootDir where source code can be found\n#. Include any wildcards under rootDir that should be excluded using \"exclude\"\n\n```Sample json\n{\n  \"extends\": \"@edx/typescript-config\",\n  \"compilerOptions\": {\n    \"rootDir\": \".\",\n    \"outDir\": \"dist\"\n  },\n  \"include\": [\"src/**/*\"],\n  \"exclude\": [\"dist\", \"node_modules\"]\n}\n```\n\n## Development\n\nThis project leverages the command line interface for webpack, jest,\neslint, and babel. Because of this, local development can be tricky. The\neasiest way to do local development on this project is to either run\nscripts inside the project in example or to test with an existing\nproject you can do the following:\n\n1.  Delete the node\\_modules directories in the host project:\n    `rm -rf node_modules/`\n2.  Move frontend-build inside the host project and delete its node\n    modules folder\n    `mv ../frontend-build ./ \u0026\u0026 rm -rf frontend-build/node_modules`\n3.  Install the development version of frontend-build\n    `npm i --save-dev @openedx/frontend-build@file:./frontend-build`.\n\n## License\n\nThe code in this repository is licensed under the AGPLv3 unless\notherwise noted.\n\nPlease see [LICENSE](LICENSE) for details.\n\n## Contributing\n\nContributions are very welcome. Please read [How To\nContribute](https://openedx.org/r/how-to-contribute) for details.\n\nThis project is currently accepting all types of contributions, bug\nfixes, security fixes, maintenance work, or new features. However,\nplease make sure to have a discussion about your new feature idea with\nthe maintainers prior to beginning development to maximize the chances\nof your change being accepted. You can start a conversation by creating\na new issue on this repo summarizing your idea.\n\n## Getting Help\n\nIf you\\'re having trouble, we have discussion forums at\n\u003chttps://discuss.openedx.org\u003e where you can connect with others in the\ncommunity.\n\nOur real-time conversations are on Slack. You can request a [Slack\ninvitation](https://openedx.org/slack), then join our [community Slack\nworkspace](https://openedx.slack.com/). Because this is a frontend\nrepository, the best place to discuss it would be in the [\\#wg-frontend\nchannel](https://openedx.slack.com/archives/C04BM6YC7A6).\n\nFor anything non-trivial, the best path is to open an issue in this\nrepository with as many details about the issue you are facing as you\ncan provide.\n\n\u003chttps://github.com/openedx/frontend-build/issues\u003e\n\nFor more information about these options, see the [Getting\nHelp](https://openedx.org/community/connect) page.\n\n## Reporting Security Issues\n\nPlease do not report security issues in public. Please email\n\u003csecurity@openedx.org\u003e.\n\n## Optimization\n\nTo increase optimization by reducing unused CSS, you can set\n`USE_PURGECSS=true` in `.env` or as ENV var in the corresponding MFE.\nHowever, note that doing this will increase build time by 30%. It\\'s\nthus not recommended to use this option during development. On the other\nhand, enabling PurgeCSS will increase browser performance for the end\nuser by as much as 20% (as measured by\n[lighthouse](https://developer.chrome.com/docs/lighthouse/overview/)).\nOperators are encouraged to do so for production deployments.\n\nFor more information about optimizing MFEs, refer to the [issue\n\\#138](https://github.com/openedx/wg-frontend/issues/138) in the\nwg-frontend repository.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenedx%2Ffrontend-build","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenedx%2Ffrontend-build","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenedx%2Ffrontend-build/lists"}