-
Notifications
You must be signed in to change notification settings - Fork 11.9k
feat(@angular/cli): add build flag --inline-asset-max-size Maximum size of asset to inline #8967
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,39 +44,60 @@ export function getStylesConfig(wco: WebpackConfigOptions) { | |
| const baseHref = wco.buildOptions.baseHref || ''; | ||
| const deployUrl = wco.buildOptions.deployUrl || ''; | ||
|
|
||
| const getPostcssUrlConfig = function() { | ||
| interface PostcssUrlConfig { | ||
| filter({ url }: { url: string}): boolean; | ||
| url: string | Function; | ||
| maxSize?: number; | ||
| } | ||
|
|
||
| let config: PostcssUrlConfig[] = []; | ||
|
|
||
| const convertRelativeUrlConfig: PostcssUrlConfig = { | ||
| // Only convert root relative URLs, which CSS-Loader won't process into require(). | ||
| filter: ({ url }: { url: string}) => url.startsWith('/') && !url.startsWith('//'), | ||
| url: ({ url }: { url: string }) => { | ||
| if (deployUrl.match(/:\/\//) || deployUrl.startsWith('/')) { | ||
| // If deployUrl is absolute or root relative, ignore baseHref & use deployUrl as is. | ||
| return `${deployUrl.replace(/\/$/, '')}${url}`; | ||
| } else if (baseHref.match(/:\/\//)) { | ||
| // If baseHref contains a scheme, include it as is. | ||
| return baseHref.replace(/\/$/, '') + | ||
| `/${deployUrl}/${url}`.replace(/\/\/+/g, '/'); | ||
| } else { | ||
| // Join together base-href, deploy-url and the original URL. | ||
| // Also dedupe multiple slashes into single ones. | ||
| return `/${baseHref}/${deployUrl}/${url}`.replace(/\/\/+/g, '/'); | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| config.push(convertRelativeUrlConfig); | ||
|
|
||
| // Do not inline any assets if the inline-asset-max-size option is negative | ||
| if (!buildOptions.inlineAssetMaxSize || buildOptions.inlineAssetMaxSize >= 0) { | ||
| const inlineAssetsConfig: PostcssUrlConfig = { | ||
| // TODO: inline .cur if not supporting IE (use browserslist to check) | ||
| filter: (asset: any) => !asset.hash && !asset.absolutePath.endsWith('.cur'), | ||
| url: 'inline', | ||
| // NOTE: maxSize is in KB | ||
| maxSize: Number.isInteger(buildOptions.inlineAssetMaxSize) ? | ||
| buildOptions.inlineAssetMaxSize : 10, | ||
| }; | ||
|
|
||
| config.push(inlineAssetsConfig); | ||
| } | ||
|
|
||
| return config; | ||
| }; | ||
|
|
||
| const postcssPluginCreator = function() { | ||
| return [ | ||
| postcssUrl({ | ||
| filter: ({ url }: { url: string }) => url.startsWith('~'), | ||
| url: ({ url }: { url: string }) => path.join(projectRoot, 'node_modules', url.substr(1)), | ||
| }), | ||
| postcssUrl([ | ||
| { | ||
| // Only convert root relative URLs, which CSS-Loader won't process into require(). | ||
| filter: ({ url }: { url: string }) => url.startsWith('/') && !url.startsWith('//'), | ||
| url: ({ url }: { url: string }) => { | ||
| if (deployUrl.match(/:\/\//) || deployUrl.startsWith('/')) { | ||
| // If deployUrl is absolute or root relative, ignore baseHref & use deployUrl as is. | ||
| return `${deployUrl.replace(/\/$/, '')}${url}`; | ||
| } else if (baseHref.match(/:\/\//)) { | ||
| // If baseHref contains a scheme, include it as is. | ||
| return baseHref.replace(/\/$/, '') + | ||
| `/${deployUrl}/${url}`.replace(/\/\/+/g, '/'); | ||
| } else { | ||
| // Join together base-href, deploy-url and the original URL. | ||
| // Also dedupe multiple slashes into single ones. | ||
| return `/${baseHref}/${deployUrl}/${url}`.replace(/\/\/+/g, '/'); | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| // TODO: inline .cur if not supporting IE (use browserslist to check) | ||
| filter: (asset: any) => !asset.hash && !asset.absolutePath.endsWith('.cur'), | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of the extra function (which is breaking the eject command). Add a condition to the filter here. |
||
| url: 'inline', | ||
| // NOTE: maxSize is in KB | ||
| maxSize: 10 | ||
| } | ||
| ]), | ||
| postcssUrl(getPostcssUrlConfig()), | ||
| autoprefixer(), | ||
| customProperties({ preserve: true }) | ||
| ]; | ||
|
|
@@ -195,7 +216,7 @@ export function getStylesConfig(wco: WebpackConfigOptions) { | |
| const ret: any = { | ||
| include: globalStylePaths, | ||
| test, | ||
| use: buildOptions.extractCss ? ExtractTextPlugin.extract(extractTextPlugin) | ||
| use: buildOptions.extractCss ? ExtractTextPlugin.extract(extractTextPlugin) | ||
| : ['style-loader', ...extractTextPlugin.use] | ||
| }; | ||
| // Save the original options as arguments for eject. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| import { ng } from '../../../utils/process'; | ||
| import { | ||
| expectFileToMatch, | ||
| expectFileMatchToExist, | ||
| writeMultipleFiles | ||
| } from '../../../utils/fs'; | ||
| import { copyProjectAsset } from '../../../utils/assets'; | ||
| import { expectToFail } from '../../../utils/utils'; | ||
|
|
||
| const imgSvg = ` | ||
| <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"> | ||
| <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" /> | ||
| </svg> | ||
| `; | ||
|
|
||
| export default function () { | ||
| return Promise.resolve() | ||
| .then(() => writeMultipleFiles({ | ||
| 'src/styles.css': ` | ||
| h1 { background: url('./assets/large.png'); } | ||
| h2 { background: url('./assets/small.svg'); } | ||
| p { background: url('./assets/small-id.svg#testID'); } | ||
| `, | ||
| 'src/app/app.component.css': ` | ||
| h3 { background: url('../assets/small.svg'); } | ||
| h4 { background: url('../assets/large.png'); } | ||
| `, | ||
| 'src/assets/small.svg': imgSvg, | ||
| 'src/assets/small-id.svg': imgSvg | ||
| })) | ||
| .then(() => copyProjectAsset('images/spectrum.png', './assets/large.png')) | ||
| .then(() => ng('build', '--extract-css', '--inline-asset-max-size=-1', '--aot')) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tests for inlining all resources and at an arbitrary non-default value would also be needed. |
||
| // Check paths are correctly generated. | ||
| .then(() => expectFileToMatch('dist/styles.bundle.css', | ||
| /url\([\'"]?large\.[0-9a-f]{20}\.png[\'"]?\)/)) | ||
| .then(() => expectFileToMatch('dist/styles.bundle.css', | ||
| /url\([\'"]?small\.[0-9a-f]{20}\.svg[\'"]?\)/)) | ||
| .then(() => expectFileToMatch('dist/styles.bundle.css', | ||
| /url\([\'"]?small-id\.[0-9a-f]{20}\.svg#testID[\'"]?\)/)) | ||
| .then(() => expectFileToMatch('dist/main.bundle.js', | ||
| /url\([\'"]?small\.[0-9a-f]{20}\.svg[\'"]?\)/)) | ||
| .then(() => expectFileToMatch('dist/main.bundle.js', | ||
| /url\([\'"]?large\.[0-9a-f]{20}\.png[\'"]?\)/)) | ||
| // Check if no inline images have been generated | ||
| .then(() => expectToFail(() => expectFileToMatch('dist/styles.bundle.css', | ||
| /url\(\\?[\'"]data:image\/svg\+xml/))) | ||
| // Check files are correctly created. | ||
| .then(() => expectFileMatchToExist('./dist', /large\.[0-9a-f]{20}\.png/)) | ||
| .then(() => expectFileMatchToExist('./dist', /small\.[0-9a-f]{20}\.svg/)) | ||
| .then(() => expectFileMatchToExist('./dist', /small-id\.[0-9a-f]{20}\.svg/)); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo "flag"