{"id":21314461,"url":"https://github.com/polyconseil/systematic","last_synced_at":"2026-03-01T13:03:21.380Z","repository":{"id":65374681,"uuid":"55062622","full_name":"Polyconseil/systematic","owner":"Polyconseil","description":"An opinionated ES6 toolchain for the browser.","archived":false,"fork":false,"pushed_at":"2020-06-15T10:57:31.000Z","size":1094,"stargazers_count":25,"open_issues_count":3,"forks_count":3,"subscribers_count":28,"default_branch":"master","last_synced_at":"2024-10-28T22:46:02.639Z","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":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Polyconseil.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-03-30T12:50:58.000Z","updated_at":"2021-01-22T05:12:15.000Z","dependencies_parsed_at":"2023-01-20T01:25:27.837Z","dependency_job_id":null,"html_url":"https://github.com/Polyconseil/systematic","commit_stats":null,"previous_names":[],"tags_count":89,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Polyconseil%2Fsystematic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Polyconseil%2Fsystematic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Polyconseil%2Fsystematic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Polyconseil%2Fsystematic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Polyconseil","download_url":"https://codeload.github.com/Polyconseil/systematic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225778840,"owners_count":17522710,"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-21T18:13:07.502Z","updated_at":"2026-03-01T13:03:19.475Z","avatar_url":"https://github.com/Polyconseil.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Systematic\n\nAn opinionated, mostly framework-agnostic toolchain to package ES6 applications and libraries for the browser.\n\n**Features :**\n\n  * Stay lazy: the toolchain already made the good choices for you.\n  * Full ES6 \u0026 PostCSS support through carefully selected \u0026 configured Webpack plugins.\n  * Paranoid code linting \u0026 styling with [standard](https://github.com/feross/standard)\n  * Framework-agnostic, standard (GNU gettext) translation file handling.\n  * Application settings management, human-editable INI files get converted into JS.\n  * Library creation, with dependencies exclusion from build\n  * Pluggable: it's easy to add commands or override features\n\n\n# Installation\n\n`npm install systematic`\n\nThe file structure expected for your application or library.\n\n```bash\n├── dist                  # what gets built\n│   ├── app.settings.js\n│   ├── bundle.js\n│   ├── bundle.js.map\n│   ├── translations.json\n│   ├── an_asset.png\n│   └── index.html\n|\n├── src                   # your code\n│    ├── some_module/\n|    |      ├── enums.js\n|    |      ├── index.js\n|    |      ├── index.spec.js\n|    |      └── models.js\n|    |\n│    ├── utils.js\n│    ├── index.html       # HTML entry point (applications)\n│    ├── index.spec.js    # A test spec file\n│    └── index.js         # JS entry point\n|\n├── webpack.config.js     # Webpack config, inherits systematic's\n├── Makefile              # Your application's Makefile\n└── systematic.ini        # systematic config\n```\n\n\n## Config file\n\n* Systematic requires a `systematic.ini` configuration file in the root folder of your project.\n\n  ```ini\n  [build]\n  ; Mandatory\n  ; Project type, can be application, component or library. An app will need an HTML entry point\n  type = library\n  ; Optional, default: vanilla\n  ; Build profile, can be vue, react, ...\n  profile = vanilla\n  ; Optional, default: dist\n  ; The relative path for the build output, defaults to dist\n  output_dir = dist\n  ; Optional, default: src\n  ; The relative path to the source dir\n  src_dir = src\n  ; Optional, default: /\n  ; The path where the application will be hosted in production (eg. '/app/')\n  public_path = /\n  ; Optional, default is blank\n  ; The locales to generate translation files\n  locales = en_US en_GB\n  ; Optional, default is []\n  ; Adds entries to the noParse config of webpack; large libraries without a require can go there.\n  ; It's only an optimization to speed up compilation in some cases, but it may break the build.\n  no_parse[] = vuetify\n  ; Optional, default is []\n  ; In \"component\" or \"library\" mode, this enables you to actually IMPORT adependency within the bundle\n  ; instead of having them all out. For instance this may be useful for undistributed dependencies, or\n  ; proprietary ones.\n  keep_dependency[] = lodash\n  ; Optional, default is 0\n  ; Analyze the bundle right after build to check the sizes.\n  analyze = 1\n\n  [serve]\n  ; Interface to listen\n  host = 127.0.0.1\n  ; Optional, default: 8080\n  ; The network port to access local website, if it's an app\n  port = 8080\n\n  [test]\n  ; Optional, default: \u003cYOUR_SRC_DIR\u003e/**/*tests.js\n  ; All files matching this pattern will be processed with Jest\n  ; It is relative to the root given to the Jest config, usually the project root\n  file_pattern = src/**/*tests.js\n  ```\n\n## Makefile\n\nSystematic uses GNU `make`. Create a Makefile at the root of your project, to import systematic commands:\n\n  ```makefile\n  include node_modules/systematic/mk/main.mk\n\n  # Your own commands\n  ```\n\n\n## Entry points\n\n* The default source folder (containing your source code and tests) is `src`. It must contain an entrypoint file named `index.js`. Example:\n\n  ```javascript\n  import somelib from 'some-lib'\n  import m1 from './module1'\n  import m2 from './module1'\n\n  // Bootstrap your project here\n  somelib.bootstrap(m1, m2)\n  ```\n\n* If your project is an application, there must be an HTML entry point named `index.html` in the source folder, containing the primary page. Your JS entry point will be automatically added.\nExample:\n\n  ```html\n  \u003c!DOCTYPE html\u003e\n  \u003chtml lang=\"en\"\u003e\n    \u003chead\u003e\n      \u003cmeta charset=\"utf-8\"\u003e\n      \u003cmeta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"\u003e\n      \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\"\u003e\n      \u003ctitle\u003eYour website\u003c/title\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n      \u003c!-- Some application bootstrap !--\u003e\n    \u003c/body\u003e\n  \u003c/html\u003e\n  ```\n\n\n# Usage\n\n`make help` gives a list of all commands.\n\n## Build\n\n`make serve` to run a local server.\n`make dist` for a prod build.\n\n## Run tests\n\n`make test` runs all test that match the test file pattern (default `**/*tests.js`).\n`make livetest` run test continuously, when a file changes.\n\n## Translations\n\n`make makemessages` extract translations from your HTML and JS files using [easygettext](https://github.com/Polyconseil/easygettext).\nThe resulting `.po` files will be in `/locale`.\n\n`make translations` generates a JSON file from them, located at `dist/translations.json`. It is automatically run with `serve`, `dist` and `test`.\n\nYou can then load them in your JS as an object:\n```javascript\nimport translations from 'dist/translations.json'`\n```\n\n## Settings\n\n`make settings` generates a file `dist/app.settings.js` from all INI files in `src/settings/` if your project is an application.\nSettings files are processed in alphabetical order, the last one overriding the previous. It is automatically run with `serve`, `dist` and `test`.\n\n**The generated file `dist/app.settings.js` needs to be included in your index.html, since it will not be added by Webpack.**\n\nAfter the app is deployed, you might want to change the settings. This part is not handled by systematic, but we recommand to regenerate the settings from INI files.\nINI files are an ideal format, as it is not error prone, ensures only settings values are changed and no javascript is added.\n\n# Build profiles\n\nFrom systematic.ini's `profile` option. For now, only the `angular` profile is supported on top of the\nnatural `vanilla` profile.\n\n## Angular\n\nValue : `angular`\n\nAdds the [ng-annotate](https://github.com/schmod/babel-plugin-angularjs-annotate) Babel plugin.\n\n## VueJS\n\nValue : `vue`\n\nAdds translation management with the vue translation token.\n\n# Override Jest or Webpack config\n\nIt's possible to override the build or test config by adding config files at the root of the projet.\n\n* For Webpack: `webpack.config.js`. Example :\n\n  ```javascript\n  // import systematic default webpack settings\n  const webpackDefaults = require('systematic').webpack_get_defaults(__dirname)\n\n  // optional overrides (an example !)\n  webpackDefaults.module.loaders.push({ test: /\\.file_extension_example$/, loader: 'my-loader' })\n\n  module.exports = webpackDefaults\n  ```\n\n\n* For Jest: `jest.conf.js`. Example:\n\n  ```javascript\n  // import systematic default jest settings\n  const jestDefaults = require('systematic').jest_get_defaults(__dirname)\n\n  // optional overrides example\n  jestDefaults.plugins.push('my-plugin')\n\n  module.exports = jest =\u003e jest.set(jestDefaults)\n  ```\n\n# Building components\n\nA component is halfway between a library and an application. You get to have an index.html page that is useful for development, but the dependencies\naren't bundled with the final package, just like a library.\n\nYou also have the choice of having the component used directly within a page, without being required from within another JS application that\ngoes through webpack.\n\nIn that regard, you have to pay attention to NOT import your dependencies using Webpack-based `import` feature and use the `/* global _, L */`\nnotation in your sources (use `import` in your tests, why not) so that your application will try and find those symbols on `window`;\nalso, use the `keep_dependency` feature in your configuration file for any dependency yo uwant bundled with.\n\n\n\n# Building libraries\n\nWhen building a library, we don't want the dependencies included in the bundle. It can cause version conflict with other packages or duplicated library imports.\n\nSystematic will set all dependencies as webpack \"externals\", which means they have to be required by the app.\n\n\n# Polyfilling\n\nSystematic uses [Babel](https://github.com/babel/babel) to transpile ES6, ES6+ code to plain ES5.\n\nPolyfilling is still needed:\n\n1. For methods that can't be transpiled: when Babel can't guess the correct transpilation for instance.\n\n  ```javascript\n  console.log('blah'.repeat(2))  // Dynamically evaluated so transpilation lets it untouched\n  ```\n\n2. To ensure expected ES6 features are present, whatever browser is used (Array.contains, for instance)\n\n## Applications\n\nYou have two solutions:\n1. Use `babel-polyfill` just like in tests. You have to include it in the app entry point, before any other import:\n\n  ```javascript\n  import 'babel-polyfill'\n  ```\nThis has the advantage of simplicity and consistency across browsers but it pollutes the global scope quite broadly.\n\n2. Import what you need from `core-js` (on which `babel-polyfill` is built) on a per case basis:\n\n  ```javascript\n  import _repeat from 'core-js/library/fn/string/repeat';\n  const myStr = _repeat('blah', 2);\n  ```\nThis method is preferred as you can precisely choose what's being added to the environment. But it's more tedious.\n\n## Libraries\nAvoid a global polyfill as it modifies global entities such as \"Function\" or \"String\".\nUse precise imports from `core-js` as described above if needed.\n\n\n# Troubleshooting\n\n## Webpack's livereload is not working properly\n\nYou should probably allow more watchers on your machine, see how [on webpack's\ndoc](https://webpack.github.io/docs/troubleshooting.html#not-enough-watchers).\n\n\n# License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolyconseil%2Fsystematic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpolyconseil%2Fsystematic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolyconseil%2Fsystematic/lists"}