fix(bundling): separate image and font resources so they do not conflict (#17763)
This commit is contained in:
parent
b736992968
commit
9c0c30edb4
BIN
e2e/web/src/test-fixtures/emitted.png
Normal file
BIN
e2e/web/src/test-fixtures/emitted.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
e2e/web/src/test-fixtures/inlined.png
Normal file
BIN
e2e/web/src/test-fixtures/inlined.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 103 B |
@ -5,16 +5,20 @@ import {
|
|||||||
createFile,
|
createFile,
|
||||||
isNotWindows,
|
isNotWindows,
|
||||||
killPorts,
|
killPorts,
|
||||||
|
listFiles,
|
||||||
newProject,
|
newProject,
|
||||||
readFile,
|
readFile,
|
||||||
rmDist,
|
rmDist,
|
||||||
runCLI,
|
runCLI,
|
||||||
runCLIAsync,
|
runCLIAsync,
|
||||||
runCypressTests,
|
runCypressTests,
|
||||||
|
tmpProjPath,
|
||||||
uniq,
|
uniq,
|
||||||
updateFile,
|
updateFile,
|
||||||
updateProjectConfig,
|
updateProjectConfig,
|
||||||
} from '@nx/e2e/utils';
|
} from '@nx/e2e/utils';
|
||||||
|
import { join } from 'path';
|
||||||
|
import { copyFileSync } from 'fs';
|
||||||
|
|
||||||
describe('Web Components Applications', () => {
|
describe('Web Components Applications', () => {
|
||||||
beforeEach(() => newProject());
|
beforeEach(() => newProject());
|
||||||
@ -29,24 +33,11 @@ describe('Web Components Applications', () => {
|
|||||||
const lintResults = runCLI(`lint ${appName}`);
|
const lintResults = runCLI(`lint ${appName}`);
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
|
|
||||||
runCLI(`build ${appName} --outputHashing none --compiler babel`);
|
|
||||||
checkFilesExist(
|
|
||||||
`dist/apps/${appName}/index.html`,
|
|
||||||
`dist/apps/${appName}/runtime.js`,
|
|
||||||
`dist/apps/${appName}/main.js`,
|
|
||||||
`dist/apps/${appName}/styles.css`
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(readFile(`dist/apps/${appName}/index.html`)).toContain(
|
|
||||||
'<link rel="stylesheet" href="styles.css">'
|
|
||||||
);
|
|
||||||
|
|
||||||
const testResults = await runCLIAsync(`test ${appName}`);
|
const testResults = await runCLIAsync(`test ${appName}`);
|
||||||
|
|
||||||
expect(testResults.combinedOutput).toContain(
|
expect(testResults.combinedOutput).toContain(
|
||||||
'Test Suites: 1 passed, 1 total'
|
'Test Suites: 1 passed, 1 total'
|
||||||
);
|
);
|
||||||
|
|
||||||
const lintE2eResults = runCLI(`lint ${appName}-e2e`);
|
const lintE2eResults = runCLI(`lint ${appName}-e2e`);
|
||||||
|
|
||||||
expect(lintE2eResults).toContain('All files pass linting.');
|
expect(lintE2eResults).toContain('All files pass linting.');
|
||||||
@ -56,6 +47,55 @@ describe('Web Components Applications', () => {
|
|||||||
expect(e2eResults).toContain('All specs passed!');
|
expect(e2eResults).toContain('All specs passed!');
|
||||||
expect(await killPorts()).toBeTruthy();
|
expect(await killPorts()).toBeTruthy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
copyFileSync(
|
||||||
|
join(__dirname, 'test-fixtures/inlined.png'),
|
||||||
|
join(tmpProjPath(), `apps/${appName}/src/app/inlined.png`)
|
||||||
|
);
|
||||||
|
copyFileSync(
|
||||||
|
join(__dirname, 'test-fixtures/emitted.png'),
|
||||||
|
join(tmpProjPath(), `apps/${appName}/src/app/emitted.png`)
|
||||||
|
);
|
||||||
|
updateFile(
|
||||||
|
`apps/${appName}/src/app/app.element.ts`,
|
||||||
|
`
|
||||||
|
// @ts-ignore
|
||||||
|
import inlined from './inlined.png';
|
||||||
|
// @ts-ignore
|
||||||
|
import emitted from './emitted.png';
|
||||||
|
export class AppElement extends HTMLElement {
|
||||||
|
public static observedAttributes = [];
|
||||||
|
connectedCallback() {
|
||||||
|
this.innerHTML = \`
|
||||||
|
<img src="\${inlined} "/>
|
||||||
|
<img src="\${emitted} "/>
|
||||||
|
\`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('app-root', AppElement);
|
||||||
|
`
|
||||||
|
);
|
||||||
|
runCLI(`build ${appName} --outputHashing none --compiler babel`);
|
||||||
|
checkFilesExist(
|
||||||
|
`dist/apps/${appName}/index.html`,
|
||||||
|
`dist/apps/${appName}/runtime.js`,
|
||||||
|
`dist/apps/${appName}/emitted.png`,
|
||||||
|
`dist/apps/${appName}/main.js`,
|
||||||
|
`dist/apps/${appName}/styles.css`
|
||||||
|
);
|
||||||
|
checkFilesDoNotExist(`dist/apps/${appName}/inlined.png`);
|
||||||
|
|
||||||
|
expect(readFile(`dist/apps/${appName}/main.js`)).toContain(
|
||||||
|
'<img src="data:image/png;base64'
|
||||||
|
);
|
||||||
|
// Should not be a JS module but kept as a PNG
|
||||||
|
expect(readFile(`dist/apps/${appName}/emitted.png`)).not.toContain(
|
||||||
|
'export default'
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(readFile(`dist/apps/${appName}/index.html`)).toContain(
|
||||||
|
'<link rel="stylesheet" href="styles.css">'
|
||||||
|
);
|
||||||
}, 500000);
|
}, 500000);
|
||||||
|
|
||||||
it('should remove previous output before building', async () => {
|
it('should remove previous output before building', async () => {
|
||||||
|
|||||||
@ -39,7 +39,6 @@
|
|||||||
"css-loader": "^6.4.0",
|
"css-loader": "^6.4.0",
|
||||||
"css-minimizer-webpack-plugin": "^5.0.0",
|
"css-minimizer-webpack-plugin": "^5.0.0",
|
||||||
"dotenv": "~10.0.0",
|
"dotenv": "~10.0.0",
|
||||||
"file-loader": "^6.2.0",
|
|
||||||
"fork-ts-checker-webpack-plugin": "7.2.13",
|
"fork-ts-checker-webpack-plugin": "7.2.13",
|
||||||
"ignore": "^5.0.4",
|
"ignore": "^5.0.4",
|
||||||
"less": "4.1.3",
|
"less": "4.1.3",
|
||||||
|
|||||||
@ -409,20 +409,38 @@ export function withWeb(pluginOptions: WithWebOptions = {}): NxWebpackPlugin {
|
|||||||
...config.module,
|
...config.module,
|
||||||
rules: [
|
rules: [
|
||||||
...(config.module.rules ?? []),
|
...(config.module.rules ?? []),
|
||||||
|
// Images: Inline small images, and emit a separate file otherwise.
|
||||||
{
|
{
|
||||||
test: /\.(bmp|png|jpe?g|gif|webp|avif)$/,
|
test: /\.(avif|bmp|gif|ico|jpe?g|png|webp)$/,
|
||||||
type: 'asset',
|
type: 'asset',
|
||||||
parser: {
|
parser: {
|
||||||
dataUrlCondition: {
|
dataUrlCondition: {
|
||||||
maxSize: 10_000, // 10 kB
|
maxSize: 10_000, // 10 kB
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
generator: {
|
||||||
|
filename: `[name]${hashFormat.file}[ext]`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
// SVG: same as image but we need to separate it so it can be swapped for SVGR in the React plugin.
|
||||||
{
|
{
|
||||||
test: /\.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)$/,
|
test: /\.svg$/,
|
||||||
loader: require.resolve('file-loader'),
|
type: 'asset',
|
||||||
options: {
|
parser: {
|
||||||
name: `[name]${hashFormat.file}.[ext]`,
|
dataUrlCondition: {
|
||||||
|
maxSize: 10_000, // 10 kB
|
||||||
|
},
|
||||||
|
},
|
||||||
|
generator: {
|
||||||
|
filename: `[name]${hashFormat.file}[ext]`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Fonts: Emit separate file and export the URL.
|
||||||
|
{
|
||||||
|
test: /\.(eot|otf|ttf|woff|woff2)$/,
|
||||||
|
type: 'asset/resource',
|
||||||
|
generator: {
|
||||||
|
filename: `[name]${hashFormat.file}[ext]`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
...rules,
|
...rules,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user