{"id":19450985,"url":"https://github.com/rixo/nollup-test-case-output-dir","last_synced_at":"2026-06-18T00:31:14.509Z","repository":{"id":42834387,"uuid":"264924065","full_name":"rixo/nollup-test-case-output-dir","owner":"rixo","description":null,"archived":false,"fork":false,"pushed_at":"2022-12-12T19:51:52.000Z","size":118,"stargazers_count":0,"open_issues_count":5,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-25T09:29:22.554Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/rixo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-18T11:53:27.000Z","updated_at":"2020-05-18T23:08:52.000Z","dependencies_parsed_at":"2023-01-28T00:31:36.659Z","dependency_job_id":null,"html_url":"https://github.com/rixo/nollup-test-case-output-dir","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rixo/nollup-test-case-output-dir","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rixo%2Fnollup-test-case-output-dir","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rixo%2Fnollup-test-case-output-dir/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rixo%2Fnollup-test-case-output-dir/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rixo%2Fnollup-test-case-output-dir/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rixo","download_url":"https://codeload.github.com/rixo/nollup-test-case-output-dir/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rixo%2Fnollup-test-case-output-dir/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34471638,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-17T02:00:05.408Z","response_time":127,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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-10T16:39:48.843Z","updated_at":"2026-06-18T00:31:14.488Z","avatar_url":"https://github.com/rixo.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Installation\n\n~~~bash\ngit clone\ncd nollup-test-case-output-dir\nyarn\n~~~\n\n## Usage\n\nRun tests:\n\n~~~bash\nyarn zoar\n~~~\n\nWatch test:\n\n~~~bash\nyarn zoar -w\n~~~\n\nIn interactive watch:\n\n- press `Enter` to rerun\n- enter `ib` to run with node debugger\n\nRun tests with debug output:\n\n~~~bash\nCUSTOM=0 yarn zoar\n~~~\n\nThe custom report format is most informative for debug. Its layout is as follow:\n\n~~~\n1. Test-specific Nollup options (passed to dev middleware)\n2. Test-specific Rollup config\n3. Rollup:\n    file writting by Rollup =\u003e URL used by the test to try to get the file\n4. Nollup:\n    dump of `Object.keys(files)` in dev middleware (only with custom branch)\n~~~\n\nExample:\n\n~~~\n1. { contentBase: 'dist' }\n2. { input: 'src/main.js', output: { dir: 'dist/app', format: 'es' } }\n3. Rollup:\n   ⚠  'dist/app/main.js' =\u003e /app/main.js\n   ⚠  'dist/app/nested-93659157.js' =\u003e /app/nested-[hash].js\n   ⚠  'dist/app/nested-d1b6ea0f.js' =\u003e /app/nested-[hash].js\n4. Nollup:\n   [ 'main.js', 'nested-[hash].js' ]\n~~~\n\n## Principle\n\nThe test principle is to run Rollup with the given config, and observe the files that are written to disk by Nollup. Then, it fires the Nollup middleware, and tries to access each file by URL, like if from a web server from `dist` folder.\n\nBoth entry point files and code splitted (dynamic imports) chunks appears in Rollup's output, and so they are tested for simplicity, but I think we only really care about the entry points actually.\n\nNOTE I have been working on a [Nollup branch](https://github.com/rixo/nollup/tree/sapper) to explore integration with Sapper (Svelte's official app generator). The branch includes a custom `onBundle` option that is used by the test to observe Nollup's output. In normal Nollup, this hook is not present, so the test won't display the files as seen by Nollup.\n\n## Issues\n\nThere are 2 classes of problems:\n\n- misalignment with Rollup for filenames of output files\n\n- it is hard or impossible to have Nollup serves bundle files at the same URL that we'd get with Rollup + web server, in some cases\n\n### Directory path is lost with `output.dir`\n\nWhen using a nested `output.dir`, Rollup keeps the full directroy path when writting entry points, but Nollup only keeps the basename.\n\nAnd so, while the file would be accessible at URL `/app/main.js` with a web server and Rollup, it is accessible at URL `/main.js` in Nollup.\n\n~~~\n=== output.dir: nested main.js =================================================\n\n{ contentBase: 'dist' }\n{\n  input: 'src/main.js',\n  inlineDynamicImports: true,\n  output: { dir: 'dist/app', format: 'es' }\n}\nRollup:\n ⚠  'dist/app/main.js' =\u003e /app/main.js\nNollup:\n[ 'main.js', 'nested-[hash].js' ]\n~~~\n\nExpected: `app/main.js` instead of `main.js`\n\n### Entry points with same basename (in different dirs) conflict\n\nWhen 2 entry points have the same basename, Rollup adds an ordinal suffix, but Nollup mashes them together.\n\n~~~\n=== output.dir: entrypoints conflict ===========================================\n\n{ contentBase: 'dist' }\n{\n  input: [ 'src/a/main.js', 'src/a/b/main.js' ],\n  output: { dir: 'dist/app', format: 'es' }\n}\nRollup:\n ⚠  'dist/app/main.js' =\u003e /app/main.js\n ⚠  'dist/app/main2.js' =\u003e /app/main2.js\nNollup:\n[ 'main.js' ]\n~~~\n\nExpected: `[ 'app/main.js', 'app/main2.js' ]`\n\n### Dynamic chunks with same basename conflict\n\nSame with dynamic chunks: they get mashed together when they share the same basename.\n\n~~~\n=== output.dir: chunk conflict =================================================\n\n{ contentBase: 'dist' }\n{\n  input: [ 'src/main.js', 'src/second.js' ],\n  output: { dir: 'dist/app', format: 'es' }\n}\nRollup:\n ⚠  'dist/app/main.js' =\u003e /app/main.js\n ⚠  'dist/app/second.js' =\u003e /app/second.js\n ⚠  'dist/app/nested-3f8ba19f.js' =\u003e /app/nested-[hash].js\n ⚠  'dist/app/nested-93659157.js' =\u003e /app/nested-[hash].js\nNollup:\n[ 'main.js', 'second.js', 'nested-[hash].js' ]\n~~~\n\nExpected: `[ ..., 'nested-[hash].js', 'nested2-[hash].js' ]` (or just anything that prevents them from having the same name an shadowing each other)\n\nAlso without hash:\n\n~~~\n=== output.dir: chunk conflict without hashes ==================================\n\n{ contentBase: 'public', baseUrl: 'dist' }\n{\n  input: [ 'src/main.js', 'src/second.js' ],\n  output: { dir: 'dist/app', format: 'es', chunkFileNames: '[name].js' }\n}\nRollup:\n ⚠  'dist/app/main.js' =\u003e /app/main.js\n ⚠  'dist/app/second.js' =\u003e /app/second.js\n ⚠  'dist/app/nested.js' =\u003e /app/nested.js\n ⚠  'dist/app/nested2.js' =\u003e /app/nested2.js\nNollup:\n[ 'main.js', 'second.js', 'nested.js' ]\n~~~\n\nExpected: `[ ..., 'nested.js', 'nested2.js' ]`\n\n### Public directory\n\nProblem: once we preserve the `output.dir` in the generated output file names to align with Rollup, then we also get the \"public\" directory in the URL generated by Nollup (e.g. `dist/app/main.js`). However, with Rollup + Webserver, a part of `output.dir` (e.g. `dist/`) would be the web root directory, and so it wouldn't appear in the URL of the file (e.g. `/app/main.js`).\n\n#### public directory same as dist\n\nWhen the public directory is the same as the output dir, we can derive the URL suffix we need to drop from `contentBase` and `output.dir`.\n\n~~~js\nconst baseUrl = output.dir.startsWith(options.contentBase)\n  ? output.dir.slice(options.contentBase.length)\n  : output.dir // actually in this case, I think the file should not be served?\n~~~\n\n~~~\n=== public dir: serve static from /dist, build to /dist ====================\n\n{ contentBase: 'dist' }\n{ input: 'src/a/main.js', output: { dir: 'dist/app', format: 'es' } }\nRollup:\n ⚠  'dist/app/main.js' =\u003e /app/main.js\nNollup:\n[ 'main.js' ]\n~~~\n\nExpected: `[ 'app/main.js' ]`\n\n#### public directory different from dist\n\nWhen the user's setup directory layout differs between prod and dev (e.g. copying static assets in prod, but serving them from source in dev), then the part of `output.dir` that must be trimmed to form the URL must be provided by the user.\n\n~~~\n=== public dir: serve static from /public, build to /dist ======================\n\n{ contentBase: 'public', baseUrl: 'dist' }\n{ input: 'src/a/main.js', output: { dir: 'dist/app', format: 'es' } }\nRollup:\n ⚠  'dist/app/main.js' =\u003e /app/main.js\nNollup:\n[ 'main.js' ]\n~~~\n\nExpected: `[ 'app/main.js' ]`\n\n## Exploratory work\n\nThe `sapper` branch of my Nollup fork passes all the above test by [adding an ordinal suffix](https://github.com/rixo/nollup/blob/2b5ae215c935183d0c788296c03e47ca498b2299/lib/impl/utils.js#L23) to entry / chunk names, [joining `output.dir`](https://github.com/rixo/nollup/blob/2b5ae215c935183d0c788296c03e47ca498b2299/lib/dev-middleware.js#L100) to produce a file URL, and [adding a `baseUrl` option](https://github.com/rixo/nollup/blob/2b5ae215c935183d0c788296c03e47ca498b2299/lib/dev-middleware.js#L103) to drop part of the output dir from the URL.\n\n~~~bash\nyarn add -D rixo/nollup#sapper\nyarn zoar\n~~~\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frixo%2Fnollup-test-case-output-dir","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frixo%2Fnollup-test-case-output-dir","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frixo%2Fnollup-test-case-output-dir/lists"}