An open API service indexing awesome lists of open source software.

https://github.com/rixo/nollup-test-case-output-dir


https://github.com/rixo/nollup-test-case-output-dir

Last synced: 11 days ago
JSON representation

Awesome Lists containing this project

README

          

## Installation

~~~bash
git clone
cd nollup-test-case-output-dir
yarn
~~~

## Usage

Run tests:

~~~bash
yarn zoar
~~~

Watch test:

~~~bash
yarn zoar -w
~~~

In interactive watch:

- press `Enter` to rerun
- enter `ib` to run with node debugger

Run tests with debug output:

~~~bash
CUSTOM=0 yarn zoar
~~~

The custom report format is most informative for debug. Its layout is as follow:

~~~
1. Test-specific Nollup options (passed to dev middleware)
2. Test-specific Rollup config
3. Rollup:
file writting by Rollup => URL used by the test to try to get the file
4. Nollup:
dump of `Object.keys(files)` in dev middleware (only with custom branch)
~~~

Example:

~~~
1. { contentBase: 'dist' }
2. { input: 'src/main.js', output: { dir: 'dist/app', format: 'es' } }
3. Rollup:
⚠ 'dist/app/main.js' => /app/main.js
⚠ 'dist/app/nested-93659157.js' => /app/nested-[hash].js
⚠ 'dist/app/nested-d1b6ea0f.js' => /app/nested-[hash].js
4. Nollup:
[ 'main.js', 'nested-[hash].js' ]
~~~

## Principle

The 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.

Both 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.

NOTE 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.

## Issues

There are 2 classes of problems:

- misalignment with Rollup for filenames of output files

- 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

### Directory path is lost with `output.dir`

When using a nested `output.dir`, Rollup keeps the full directroy path when writting entry points, but Nollup only keeps the basename.

And 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.

~~~
=== output.dir: nested main.js =================================================

{ contentBase: 'dist' }
{
input: 'src/main.js',
inlineDynamicImports: true,
output: { dir: 'dist/app', format: 'es' }
}
Rollup:
⚠ 'dist/app/main.js' => /app/main.js
Nollup:
[ 'main.js', 'nested-[hash].js' ]
~~~

Expected: `app/main.js` instead of `main.js`

### Entry points with same basename (in different dirs) conflict

When 2 entry points have the same basename, Rollup adds an ordinal suffix, but Nollup mashes them together.

~~~
=== output.dir: entrypoints conflict ===========================================

{ contentBase: 'dist' }
{
input: [ 'src/a/main.js', 'src/a/b/main.js' ],
output: { dir: 'dist/app', format: 'es' }
}
Rollup:
⚠ 'dist/app/main.js' => /app/main.js
⚠ 'dist/app/main2.js' => /app/main2.js
Nollup:
[ 'main.js' ]
~~~

Expected: `[ 'app/main.js', 'app/main2.js' ]`

### Dynamic chunks with same basename conflict

Same with dynamic chunks: they get mashed together when they share the same basename.

~~~
=== output.dir: chunk conflict =================================================

{ contentBase: 'dist' }
{
input: [ 'src/main.js', 'src/second.js' ],
output: { dir: 'dist/app', format: 'es' }
}
Rollup:
⚠ 'dist/app/main.js' => /app/main.js
⚠ 'dist/app/second.js' => /app/second.js
⚠ 'dist/app/nested-3f8ba19f.js' => /app/nested-[hash].js
⚠ 'dist/app/nested-93659157.js' => /app/nested-[hash].js
Nollup:
[ 'main.js', 'second.js', 'nested-[hash].js' ]
~~~

Expected: `[ ..., 'nested-[hash].js', 'nested2-[hash].js' ]` (or just anything that prevents them from having the same name an shadowing each other)

Also without hash:

~~~
=== output.dir: chunk conflict without hashes ==================================

{ contentBase: 'public', baseUrl: 'dist' }
{
input: [ 'src/main.js', 'src/second.js' ],
output: { dir: 'dist/app', format: 'es', chunkFileNames: '[name].js' }
}
Rollup:
⚠ 'dist/app/main.js' => /app/main.js
⚠ 'dist/app/second.js' => /app/second.js
⚠ 'dist/app/nested.js' => /app/nested.js
⚠ 'dist/app/nested2.js' => /app/nested2.js
Nollup:
[ 'main.js', 'second.js', 'nested.js' ]
~~~

Expected: `[ ..., 'nested.js', 'nested2.js' ]`

### Public directory

Problem: 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`).

#### public directory same as dist

When 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`.

~~~js
const baseUrl = output.dir.startsWith(options.contentBase)
? output.dir.slice(options.contentBase.length)
: output.dir // actually in this case, I think the file should not be served?
~~~

~~~
=== public dir: serve static from /dist, build to /dist ====================

{ contentBase: 'dist' }
{ input: 'src/a/main.js', output: { dir: 'dist/app', format: 'es' } }
Rollup:
⚠ 'dist/app/main.js' => /app/main.js
Nollup:
[ 'main.js' ]
~~~

Expected: `[ 'app/main.js' ]`

#### public directory different from dist

When 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.

~~~
=== public dir: serve static from /public, build to /dist ======================

{ contentBase: 'public', baseUrl: 'dist' }
{ input: 'src/a/main.js', output: { dir: 'dist/app', format: 'es' } }
Rollup:
⚠ 'dist/app/main.js' => /app/main.js
Nollup:
[ 'main.js' ]
~~~

Expected: `[ 'app/main.js' ]`

## Exploratory work

The `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.

~~~bash
yarn add -D rixo/nollup#sapper
yarn zoar
~~~