Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: keep order of script tags #2571

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/good-bats-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@web/rollup-plugin-polyfills-loader': patch
'@web/rollup-plugin-html': patch
---

fix: keep order of script tags
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## editors
/.idea
/.vscode
*~
koddsson marked this conversation as resolved.
Show resolved Hide resolved

# @11ty/eleventy-cache-assets
.cache
Expand Down Expand Up @@ -29,6 +30,7 @@ dist-types
.wireit
/dist
/packages/*/dist
/packages/*/demo/dist
tsconfig.tsbuildinfo
_site
_site-dev
Expand Down
6 changes: 3 additions & 3 deletions packages/rollup-plugin-html/demo/mpa/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ <h1>Index</h1>
</li>

<li>
<a href="/pages/page-B.html">B</a>
<a href="/pages/page-b.html">B</a>
</li>

<li>
<a href="/pages/page-C.html">C</a>
<a href="/pages/page-c.html">C</a>
</li>
</ul>
</ul>
4 changes: 2 additions & 2 deletions packages/rollup-plugin-html/demo/mpa/pages/page-a.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ <h1>Page A</h1>
</li>

<li>
<a href="/pages/page-B.html">B</a>
<a href="/pages/page-b.html">B</a>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see why these changed from upper case to lowercase letters 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh these were changed manually! Do we need to change these? I'd rather make the smallest change possible so it's easier to review. If possible I'd like to revert these changes to the HTML files even though they are probably technically correct.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do this in a separate PR. The demo will not work without the change (on linux) because the file name is page-b.html.

</li>

<li>
<a href="/pages/page-C.html">C</a>
<a href="/pages/page-c.html">C</a>
</li>
</ul>

Expand Down
4 changes: 2 additions & 2 deletions packages/rollup-plugin-html/demo/mpa/pages/page-b.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ <h1>Page B</h1>
</li>

<li>
<a href="/pages/page-B.html">B</a>
<a href="/pages/page-b.html">B</a>
</li>

<li>
<a href="/pages/page-C.html">C</a>
<a href="/pages/page-c.html">C</a>
</li>
</ul>

Expand Down
4 changes: 2 additions & 2 deletions packages/rollup-plugin-html/demo/mpa/pages/page-c.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ <h1>Page C</h1>
</li>

<li>
<a href="/pages/page-B.html">B</a>
<a href="/pages/page-b.html">B</a>
</li>

<li>
<a href="/pages/page-C.html">C</a>
<a href="/pages/page-c.html">C</a>
</li>
</ul>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ export function extractModules(params: ExtractModulesParams) {
attributes,
code,
});
moduleImports.push({
importPath,
attributes,
});
}
remove(scriptNode);
} else {
Expand Down
2 changes: 1 addition & 1 deletion packages/rollup-plugin-html/src/input/getInputData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function createInputData(params: CreateInputDataParams): InputData {
html: result.htmlWithoutModules,
name,
inlineModules: result.inlineModules,
moduleImports: [...result.moduleImports, ...result.inlineModules],
moduleImports: result.moduleImports,
assets: result.assets,
filePath,
};
Expand Down
17 changes: 16 additions & 1 deletion packages/rollup-plugin-html/src/output/getEntrypointBundles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ interface Entrypoint {
attributes?: Attribute[];
}

interface EntrypointsUnsorted {
[key: string]: Entrypoint;
}

export function getEntrypointBundles(params: GetEntrypointBundlesParams) {
const { pluginOptions, generatedBundles, inputModuleIds, outputDir, htmlFileName } = params;
const entrypointBundles: Record<string, EntrypointBundle> = {};
Expand All @@ -63,6 +67,7 @@ export function getEntrypointBundles(params: GetEntrypointBundlesParams) {
}

const entrypoints: Entrypoint[] = [];
const entrypointsUnsorted: EntrypointsUnsorted = {};
for (const chunkOrAsset of Object.values(bundle)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the assets in bundle come to us not in the order that they were parsed in? I wonder why that is. You think it's something in Rollup or in some other Modern Web code?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking being that if we are creating this asset list incorrectly somewhere else (and not Rollup) we could delve deeper into the issue and try to fix it at it's root rather than sorting the asset/chunk list here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entrypoints is just gathered through bundles and object values. See getEntrypointBundles in the same file. The order could be different from file to file. And on top of that, Object.values is not guaranteed to have a specific order.

if (chunkOrAsset.type === 'chunk') {
const chunk = chunkOrAsset;
Expand All @@ -76,11 +81,21 @@ export function getEntrypointBundles(params: GetEntrypointBundlesParams) {
htmlFileName,
fileName: chunkOrAsset.fileName,
});
entrypoints.push({ importPath, chunk: chunkOrAsset, attributes: found.attributes });
entrypointsUnsorted[chunk.facadeModuleId] = {
importPath,
chunk: chunkOrAsset,
attributes: found.attributes,
};
}
}
}
}

for (const mod of inputModuleIds) {
if (!entrypointsUnsorted[mod.importPath]) continue;
entrypoints.push(entrypointsUnsorted[mod.importPath]);
}

entrypointBundles[name] = { name, options, bundle, entrypoints };
}

Expand Down
30 changes: 30 additions & 0 deletions packages/rollup-plugin-html/test/rollup-plugin-html.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,36 @@ describe('rollup-plugin-html', () => {
);
});

it('resolves modules in original order', async () => {
const config = {
plugins: [
rollupPluginHTML({
rootDir,
input: {
name: 'index.html',
html:
'<h1>Hello world</h1>' +
'<script type="module">import "./entrypoint-a.js";</script>' +
'<script type="module" src="./entrypoint-b.js"></script>',
},
}),
],
};

const bundle = await rollup(config);
const { output } = await bundle.generate(outputConfig);
expect(output.length).to.equal(4);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this asserting? What is the actual output?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most all of the outputs was reversed. a + b would become b + a.

const hash = '5ec680a4efbb48ae254268ab1defe610';
const { code: appCode } = getChunk(output, `inline-module-${hash}.js`);
expect(appCode).to.include("console.log('entrypoint-a.js');");
expect(stripNewlines(getAsset(output, 'index.html').source)).to.equal(
'<html><head></head><body><h1>Hello world</h1>' +
`<script type="module" src="./inline-module-${hash}.js"></script>` +
'<script type="module" src="./entrypoint-b.js"></script>' +
'</body></html>',
);
});

it('resolves inline module imports relative to the HTML file', async () => {
const config = {
plugins: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ describe('extractModules()', () => {
attributes: [],
},
]);
expect(moduleImports).to.eql([]);
expect(moduleImports.length).to.eql(2);
expect(htmlWithoutModules).to.eql(
'<html><head></head><body><div>before</div><div>after</div></body></html>',
);
Expand Down Expand Up @@ -164,7 +164,7 @@ describe('extractModules()', () => {
attributes: [],
},
]);
expect(moduleImports).to.eql([]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you help me understand this change? From the code changed I don't understand why these tests change.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See packages/rollup-plugin-html/src/input/getInputData.ts
The order between inline and other modules was lost because they was gathered in two different lists. Then they was merged together upon return, making the inline modules always come after the other modules. I changed it to put all modules including inline modules in the sam list from the start. Thus, the moduleImports lists is no longer empty if there is inlineModules.

expect(moduleImports.length).to.eql(2);
expect(htmlWithoutModules).to.eql(
'<html><head></head><body><div>before</div><div>after</div></body></html>',
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<html><head>

<link rel="preload" href="./entrypoint-b.js" as="script" crossorigin="anonymous" />
<link rel="preload" href="./entrypoint-a.js" as="script" crossorigin="anonymous" />
<link rel="preload" href="./entrypoint-b.js" as="script" crossorigin="anonymous" />
</head><body><script>(function () {
function loadScript(src, type, attributes) {
return new Promise(function (resolve) {
Expand Down Expand Up @@ -33,9 +33,9 @@
}
function loadFiles() {
[function () {
return loadScript('./entrypoint-b.js', 'module', []);
}, function () {
return loadScript('./entrypoint-a.js', 'module', []);
}, function () {
return loadScript('./entrypoint-b.js', 'module', []);
}].reduce(function (a, c) {
return a.then(c);
}, Promise.resolve());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<html><head>

<link rel="preload" href="./entrypoint-b.js" as="script" crossorigin="anonymous" />
<link rel="preload" href="./entrypoint-a.js" as="script" crossorigin="anonymous" />
<link rel="preload" href="./entrypoint-b.js" as="script" crossorigin="anonymous" />
</head><body><script>(function () {
function loadScript(src, type, attributes) {
return new Promise(function (resolve) {
Expand Down Expand Up @@ -33,12 +33,12 @@
}
function loadFiles() {
[function () {
return loadScript('./entrypoint-b.js', 'module', []);
}, function () {
return loadScript('./entrypoint-a.js', 'module', [{
"name": "keep-this-attribute",
"value": ""
}]);
}, function () {
return loadScript('./entrypoint-b.js', 'module', []);
}].reduce(function (a, c) {
return a.then(c);
}, Promise.resolve());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<html><head>

<link rel="preload" href="./entrypoint-b.js" as="script" crossorigin="anonymous" />
<link rel="preload" href="./entrypoint-a.js" as="script" crossorigin="anonymous" />
<link rel="preload" href="./entrypoint-b.js" as="script" crossorigin="anonymous" />
</head><body><script>(function () {
function loadScript(src, type, attributes) {
return new Promise(function (resolve) {
Expand Down Expand Up @@ -33,9 +33,9 @@
}
function loadFiles() {
[function () {
return loadScript('./entrypoint-b.js', 'module', []);
}, function () {
return loadScript('./entrypoint-a.js', 'module', []);
}, function () {
return loadScript('./entrypoint-b.js', 'module', []);
}].reduce(function (a, c) {
return a.then(c);
}, Promise.resolve());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<html><head>

<link rel="preload" href="./entrypoint-b.js" as="script" crossorigin="anonymous" />
<link rel="preload" href="./entrypoint-a.js" as="script" crossorigin="anonymous" />
<link rel="preload" href="./entrypoint-b.js" as="script" crossorigin="anonymous" />
</head><body>
<script type="module" src="./entrypoint-b.js"></script>
<script type="module" src="./entrypoint-a.js" keep-this-attribute=""></script>
<script type="module" src="./entrypoint-b.js"></script>

</body></html>
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<html><head>

<link rel="preload" href="./entrypoint-b.js" as="script" crossorigin="anonymous" />
<link rel="preload" href="./entrypoint-a.js" as="script" crossorigin="anonymous" />
<link rel="preload" href="./entrypoint-b.js" as="script" crossorigin="anonymous" />
</head><body>
<script type="module" src="./entrypoint-b.js"></script>
<script type="module" src="./entrypoint-a.js"></script>
<script type="module" src="./entrypoint-b.js"></script>

</body></html>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<html><head>

<link rel="preload" href="../entrypoint-b.js" as="script" crossorigin="anonymous" />
<link rel="preload" href="../entrypoint-a.js" as="script" crossorigin="anonymous" />
<link rel="preload" href="../entrypoint-b.js" as="script" crossorigin="anonymous" />
</head><body><script>(function () {
function loadScript(src, type, attributes) {
return new Promise(function (resolve) {
Expand Down Expand Up @@ -33,9 +33,9 @@
}
function loadFiles() {
[function () {
return loadScript('../entrypoint-b.js', 'module', []);
}, function () {
return loadScript('../entrypoint-a.js', 'module', []);
}, function () {
return loadScript('../entrypoint-b.js', 'module', []);
}].reduce(function (a, c) {
return a.then(c);
}, Promise.resolve());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<html><head>

<link rel="preload" href="./entrypoint-b.js" as="script" />
<link rel="preload" href="./entrypoint-a.js" as="script" />
<link rel="preload" href="./entrypoint-b.js" as="script" />
</head><body><script>(function () {
function loadScript(src, type, attributes) {
return new Promise(function (resolve) {
Expand Down Expand Up @@ -31,9 +31,9 @@
polyfills.push(loadScript('./polyfills/systemjs.dabf4e8006a3be11acd4b6981abd9943.js'));
function loadFiles() {
[function () {
return System.import('./entrypoint-b.js');
}, function () {
return System.import('./entrypoint-a.js');
}, function () {
return System.import('./entrypoint-b.js');
}].reduce(function (a, c) {
return a.then(c);
}, Promise.resolve());
Expand Down