{"id":16229224,"url":"https://github.com/morris/samd","last_synced_at":"2025-03-19T13:31:41.130Z","repository":{"id":42278120,"uuid":"257027723","full_name":"morris/samd","owner":"morris","description":"A tiny, static AMD API implementation","archived":false,"fork":false,"pushed_at":"2023-01-06T03:47:21.000Z","size":762,"stargazers_count":9,"open_issues_count":17,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-28T19:01:27.985Z","etag":null,"topics":["amd","es6","javascript","module-bundler","typescript","web"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/morris.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-04-19T14:59:37.000Z","updated_at":"2024-03-21T23:01:32.000Z","dependencies_parsed_at":"2023-02-05T06:16:16.098Z","dependency_job_id":null,"html_url":"https://github.com/morris/samd","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morris%2Fsamd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morris%2Fsamd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morris%2Fsamd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morris%2Fsamd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/morris","download_url":"https://codeload.github.com/morris/samd/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243996162,"owners_count":20380959,"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":["amd","es6","javascript","module-bundler","typescript","web"],"created_at":"2024-10-10T12:57:44.081Z","updated_at":"2025-03-19T13:31:40.814Z","avatar_url":"https://github.com/morris.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SAMD\n\nA tiny, static [AMD](https://github.com/amdjs/amdjs-api) API implementation\nthat allows __including AMD modules in regular script tags.__\n\n*SAMD is currently experimental/awaiting feedback.*\n\n- __1.3 KB__ minified \u0026 gzipped\n- No dynamic loading; all scripts are __loaded by the browser__\n- Works in __every browser alive__\n- Supports `\u003cscript defer\u003e` \u0026 `\u003cscript async\u003e`\n- Allows progressive optimizations without impact on development\n\nWhen combined with [TypeScript](typescriptlang.org),\nSAMD may be used as an alternative to traditional JS bundling\n(e.g. `webpack` or `rollup`).\nThis is the main use case for SAMD, as described below.\nAn example project can be inspected under `/example`.\n\n[Try the example online](https://rawcdn.githack.com/morris/samd/0.1.0/example/public/index.html)\n\n## Usage\n\nSAMD enables inclusion of UMD/AMD modules in regular `script` tags:\n\n```html\n\u003cscript src=\"https://unpkg.com/samd@0/dist/samd.js\" crossorigin\u003e\u003c/script\u003e\n\u003cscript async src=\"https://unpkg.com/moment@2/moment.js\" crossorigin\u003e\u003c/script\u003e\n\u003cscript async src=\"https://unpkg.com/lodash@4/lodash.js\" crossorigin\u003e\u003c/script\u003e\n\u003c!-- more UMD/AMD dependencies... --\u003e\n\u003cscript\u003e\n  require(['moment', 'lodash'], function (moment, _) {\n    // use dependencies\n  });\n\u003c/script\u003e\n```\n\nNo additional script loading or special markup is required.\n\n## Usage with TypeScript\n\nGiven a regular ES6/TypeScript project, with NPM dependencies and\n[TypeScript configuration](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html)\nin place, TypeScript is able to produce one-file AMD builds with wide browser\ncompatibility out-of-the-box:\n\n```sh\ntsc --outFile scripts/dist/app.js --target ES5 --module AMD\n```\n\nThis generates an ES5 AMD bundle of the project, not including NPM modules but\nexplicitly referencing NPM imports as AMD dependencies.\nNote that TypeScript is able to handle JS/JSX projects by using `--allowJs`.\n\nThis _application bundle_ can be used directly in a website\nby including SAMD and UMD builds of the application dependencies from\ne.g. [unpkg](https://unpkg.com/):\n\n```html\n\u003cdiv id=\"root\"\u003e\u003c/div\u003e\n\u003cscript src=\"https://unpkg.com/samd@0/dist/samd.js\" crossorigin\u003e\u003c/script\u003e\n\u003cscript src=\"https://unpkg.com/react@16/umd/react.development.js\" crossorigin\u003e\u003c/script\u003e\n\u003cscript src=\"https://unpkg.com/react-dom@16/umd/react-dom.development.js\" crossorigin\u003e\u003c/script\u003e\n\u003c!-- more UMD/AMD dependencies... --\u003e\n\u003cscript src=\"scripts/dist/app.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  // assuming the entry point is index.ts/index.js and it exports an init() function:\n  require([\"scripts/index\"], function (index) {\n    index.init();\n  });\n\u003c/script\u003e\n```\n\nSAMD infers module IDs from script `src` attributes, allowing\nthe original NPM imports to be resolved from the application bundle.\n\nThis setup is sufficient for development:\n\n- It works in modern browsers.\n- Application code is based on modern JS/TypeScript with ES6 imports.\n- TypeScript's watch mode may be used to continuously build the application bundle.\n- Source maps are supported.\n\nNote that CommonJS-only dependencies cannot be used.\nDependencies must provide UMD/AMD builds (most popular libraries do, though).\n\n### Production\n\nIn production environments, the respective production/minified builds of\ndependencies should be used. Polyfills may be included using e.g.\n[polyfill.io](https://polyfill.io/). For further optimization, the application\nbundle may be minified through [terser](https://terser.org/).\n\n```html\n\u003cscript src=\"https://polyfill.io/v3/polyfill.min.js?features=fetch,Promise\" crossorigin\u003e\u003c/script\u003e\n\u003cscript src=\"https://unpkg.com/samd@0/dist/samd.min.js\" crossorigin\u003e\u003c/script\u003e\n\u003cscript src=\"https://unpkg.com/react@16/umd/react.production.min.js\" crossorigin\u003e\u003c/script\u003e\n\u003cscript src=\"https://unpkg.com/react-dom@16/umd/react-dom.production.min.js\" crossorigin\u003e\u003c/script\u003e\n\u003cscript src=\"scripts/dist/app.min.js\"\u003e\u003c/script\u003e\n```\n\nIt is reasonable to serve separate HTML documents for development and\nproduction environments. Employ templating techniques at build-time or on\nserver-side as needed.\n\nBecause of `unpkg`'s CDN, this setup is fairly performant when using popular\nlibraries. It is also widely compatible regarding browser support, depending on\nthe chosen TypeScript target.\n\n### Self-hosting\n\nIf vendor dependencies need to be self-hosted, it is recommended\nto copy the respective builds from `node_modules` to e.g. `scripts/vendor`.\nCompiling the set of polyfills is out of scope for this document.\n\n```html\n\u003cscript src=\"scripts/vendor/polyfills.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"scripts/vendor/samd.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"scripts/vendor/react.production.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"scripts/vendor/react-dom.production.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"scripts/dist/app.min.js\"\u003e\u003c/script\u003e\n```\n\nIt is encouraged to automate copying and other build steps through one or\nmore shell scripts (see `build.sh` in the example project).\nRemember that SAMD infers AMD module IDs from script filenames\n(after last `/`, before first `.`, while still allowing `@org/package`).\n\nWhen served with HTTP/2, this setup is sufficiently performant for a wide range\nof websites.\n\n### Bundling\n\nWhen having many vendor dependencies or when HTTP/2 is unavailable,\nall scripts may be concatenated into a single file\n(optionally running it through `terser` again).\n\n```html\n\u003cscript src=\"scripts/bundle.min.js\"\u003e\u003c/script\u003e\n```\n\nHowever, because UMD modules usually define anonymous modules,\nSAMD is not able to identify individual module IDs of a bundle without user\ninput, so bundling cannot work by simple concatenation.\n\nFor this use case, SAMD ships with a CLI to infer and inject module IDs into\ngiven UMD module files (see `build.sh` in the example project).\nThis CLI can also be used for concatenation.\n\n```sh\nsamd -o scripts/dist/bundle.js \\\n  scripts/vendor/polyfills.min.js \\\n  scripts/vendor/samd.min.js \\\n  scripts/vendor/react.production.min.js \\\n  scripts/vendor/react-dom.production.min.js \\\n  scripts/dist/app.min.js\nterser scripts/dist/bundle.js -o scripts.dist.bundle.js\n```\n\nNote that this only has to be done in bundling scenarios.\n\n### Libraries\n\nSAMD is only useful for applications.\nPackages for the web should be distributed as UMD for maximum compatibility.\n\n## Conclusion\n\nThe presented TypeScript/SAMD-based workflow has useful properties and is fully\ncompatible with the web platform.\n\n- Works with modern ES6/TypeScript projects, with little implications.\n- Wide browser compatibility (even Internet Explorer)\n- Loading of scripts is handled and optimized by the browser.\n- Production optimizations are progressive and don't impact development.\n- Bundling is (almost) reduced to simple concatenation.\n- Bundling does not require configuration; simple shell scripts are sufficient\n  and provide additional flexibility.\n\nAt any point of the workflow, it is advised to measure page load performance\nand user experience, and only proceed optimizing if needed.\n\n## Limitations\n\n- Dependencies must provide AMD/UMD builds.\n- Multiple versions of dependencies are not supported.\n- CommonJS is not supported.\n- No tree-shaking.\n- Relative module dependencies are not supported (yet).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorris%2Fsamd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmorris%2Fsamd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorris%2Fsamd/lists"}