Skip to content

Commit

Permalink
fix(bundling): separate image and font resources so they do not confl…
Browse files Browse the repository at this point in the history
…ict (#17763)
  • Loading branch information
jaysoo committed Jun 26, 2023
1 parent b736992 commit 9c0c30e
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 19 deletions.
Binary file added e2e/web/src/test-fixtures/emitted.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added e2e/web/src/test-fixtures/inlined.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 53 additions & 13 deletions e2e/web/src/web.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@ import {
createFile,
isNotWindows,
killPorts,
listFiles,
newProject,
readFile,
rmDist,
runCLI,
runCLIAsync,
runCypressTests,
tmpProjPath,
uniq,
updateFile,
updateProjectConfig,
} from '@nx/e2e/utils';
import { join } from 'path';
import { copyFileSync } from 'fs';

describe('Web Components Applications', () => {
beforeEach(() => newProject());
Expand All @@ -29,24 +33,11 @@ describe('Web Components Applications', () => {
const lintResults = runCLI(`lint ${appName}`);
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}`);

expect(testResults.combinedOutput).toContain(
'Test Suites: 1 passed, 1 total'
);

const lintE2eResults = runCLI(`lint ${appName}-e2e`);

expect(lintE2eResults).toContain('All files pass linting.');
Expand All @@ -56,6 +47,55 @@ describe('Web Components Applications', () => {
expect(e2eResults).toContain('All specs passed!');
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);

it('should remove previous output before building', async () => {
Expand Down
1 change: 0 additions & 1 deletion packages/webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
"css-loader": "^6.4.0",
"css-minimizer-webpack-plugin": "^5.0.0",
"dotenv": "~10.0.0",
"file-loader": "^6.2.0",
"fork-ts-checker-webpack-plugin": "7.2.13",
"ignore": "^5.0.4",
"less": "4.1.3",
Expand Down
28 changes: 23 additions & 5 deletions packages/webpack/src/utils/with-web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,20 +409,38 @@ export function withWeb(pluginOptions: WithWebOptions = {}): NxWebpackPlugin {
...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',
parser: {
dataUrlCondition: {
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: /\.svg$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 10_000, // 10 kB
},
},
generator: {
filename: `[name]${hashFormat.file}[ext]`,
},
},
// Fonts: Emit separate file and export the URL.
{
test: /\.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)$/,
loader: require.resolve('file-loader'),
options: {
name: `[name]${hashFormat.file}.[ext]`,
test: /\.(eot|otf|ttf|woff|woff2)$/,
type: 'asset/resource',
generator: {
filename: `[name]${hashFormat.file}[ext]`,
},
},
...rules,
Expand Down

1 comment on commit 9c0c30e

@vercel
Copy link

@vercel vercel bot commented on 9c0c30e Jun 26, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

nx-dev – ./

nx-dev-nrwl.vercel.app
nx.dev
nx-five.vercel.app
nx-dev-git-master-nrwl.vercel.app

Please sign in to comment.