refactor(@angular-devkit/build-angular): remove support for Stylus

The usage of Stylus in the CLI is minimal and this package never reached version 1.

BREAKING CHANGE:

Deprecated support for Stylus has been removed. The Stylus package has never reached a stable version and its usage in the Angular CLI is minimal. It's recommended to migrate to another CSS preprocessor that the Angular CLI supports.
This commit is contained in:
Alan Agius 2022-09-16 11:51:27 +00:00 committed by Douglas Parker
parent 12931ba8c3
commit 2ba44a433c
17 changed files with 18 additions and 143 deletions

View File

@ -8,9 +8,8 @@ digraph G {
"*.css" -> "postcss-loader with postcss-import, ./postcss-cli-resources.ts, autoprefixer";
"*.scss\|sass" -> "sass-loader" -> "postcss-loader with postcss-import, ./postcss-cli-resources.ts, autoprefixer";
"*.less" -> "less-loader" -> "postcss-loader with postcss-import, ./postcss-cli-resources.ts, autoprefixer";
"*.styl" -> "stylus-loader" -> "postcss-loader with postcss-import, ./postcss-cli-resources.ts, autoprefixer";
"postcss-loader with postcss-import, ./postcss-cli-resources.ts, autoprefixer" -> "raw-loader, ./optimize-css-webpack-plugin.ts" [label="component style?"];
"raw-loader" -> "./optimize-css-webpack-plugin.ts"
"postcss-loader with postcss-import, ./postcss-cli-resources.ts, autoprefixer" -> "style-loader, ./raw-css-loader.ts, and mini-css-extract-plugin" [label="global style?"];
"style-loader, ./raw-css-loader.ts, and mini-css-extract-plugin" -> "./optimize-css-webpack-plugin.ts"
}
}

View File

@ -54,8 +54,8 @@ This is used for conditional loading of code at build time.
Two types of stylesheets are used in the build system: global stylesheets and component stylesheets.
Global stylesheets are injected into the `index.html` file, while component stylesheets are loaded directly into compiled Angular components.
The build system supports plain CSS stylesheets as well as the Sass, LESS and Stylus CSS pre-processors.
Stylesheet processing functionality is provided by `sass-loader`, `less-loader`, `stylus-loader`, `postcss-loader`, `postcss-import`, augmented in the build system by custom webpack plugins.
The build system supports plain CSS stylesheets as well as the Sass and LESS CSS pre-processors.
Stylesheet processing functionality is provided by `sass-loader`, `less-loader`, `postcss-loader`, `postcss-import`, augmented in the build system by custom webpack plugins.
### Assets

View File

@ -204,8 +204,6 @@
"source-map-loader": "4.0.0",
"source-map-support": "0.5.21",
"spdx-satisfies": "^5.0.0",
"stylus": "0.59.0",
"stylus-loader": "7.0.0",
"symbol-observable": "4.0.0",
"tar": "^6.1.6",
"terser": "5.15.0",

View File

@ -170,8 +170,6 @@ ts_library(
"@npm//semver",
"@npm//source-map-loader",
"@npm//source-map-support",
"@npm//stylus",
"@npm//stylus-loader",
"@npm//terser",
"@npm//text-table",
"@npm//tree-kill",

View File

@ -57,8 +57,6 @@
"semver": "7.3.7",
"source-map-loader": "4.0.0",
"source-map-support": "0.5.21",
"stylus": "0.59.0",
"stylus-loader": "7.0.0",
"terser": "5.15.0",
"text-table": "0.2.0",
"tree-kill": "1.2.2",

View File

@ -72,7 +72,7 @@
"input": {
"type": "string",
"description": "The file to include.",
"pattern": "\\.(?:css|scss|sass|less|styl)$"
"pattern": "\\.(?:css|scss|sass|less)$"
},
"bundleName": {
"type": "string",
@ -91,7 +91,7 @@
{
"type": "string",
"description": "The file to include.",
"pattern": "\\.(?:css|scss|sass|less|styl)$"
"pattern": "\\.(?:css|scss|sass|less)$"
}
]
}

View File

@ -72,7 +72,7 @@
"input": {
"type": "string",
"description": "The file to include.",
"pattern": "\\.(?:css|scss|sass|less|styl)$"
"pattern": "\\.(?:css|scss|sass|less)$"
},
"bundleName": {
"type": "string",
@ -91,7 +91,7 @@
{
"type": "string",
"description": "The file to include.",
"pattern": "\\.(?:css|scss|sass|less|styl)$"
"pattern": "\\.(?:css|scss|sass|less)$"
}
]
}

View File

@ -13,8 +13,8 @@ import { dirname } from 'path';
import { browserBuild, createArchitect, host } from '../../../testing/test-utils';
describe('Browser Builder styles', () => {
const extensionsWithImportSupport = ['css', 'scss', 'less', 'styl'];
const extensionsWithVariableSupport = ['scss', 'less', 'styl'];
const extensionsWithImportSupport = ['css', 'scss', 'less'];
const extensionsWithVariableSupport = ['scss', 'less'];
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" />
@ -223,9 +223,6 @@ describe('Browser Builder styles', () => {
if (ext === 'scss') {
variableAssignment = '$primary-color:';
variablereference = '$primary-color';
} else if (ext === 'styl') {
variableAssignment = '$primary-color =';
variablereference = '$primary-color';
} else if (ext === 'less') {
variableAssignment = '@primary-color:';
variablereference = '@primary-color';

View File

@ -13,7 +13,7 @@ import { Type } from '../../schema';
import { BASE_OPTIONS, BROWSER_BUILDER_INFO, describeBuilder } from '../setup';
describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
const CSS_EXTENSIONS = ['css', 'scss', 'less', 'styl'];
const CSS_EXTENSIONS = ['css', 'scss', 'less'];
const BUDGET_NOT_MET_REGEXP = /Budget .+ was not met by/;
describe('Option: "bundleBudgets"', () => {

View File

@ -58,29 +58,6 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
harness.expectFile('dist/main.js').content.toContain('color: green');
});
// Stylus currently does not function due to the sourcemap logic within the `stylus-loader`
// which tries to read each stylesheet directly from disk. In this case, each stylesheet is
// virtual and cannot be read from disk. This issue affects data URIs in general.
// xit('supports Stylus inline component styles when set to "stylus"', async () => {
// harness.useTarget('build', {
// ...BASE_OPTIONS,
// inlineStyleLanguage: InlineStyleLanguage.Stylus,
// aot,
// });
// await harness.modifyFile('src/app/app.component.ts', (content) =>
// content.replace(
// '__STYLE_MARKER__',
// '$primary = green;\\nh1 { color: $primary; }',
// ),
// );
// const { result } = await harness.executeOnce();
// expect(result?.success).toBe(true);
// harness.expectFile('dist/main.js').content.toContain('color: green');
// });
it('supports Less inline component styles when set to "less"', async () => {
harness.useTarget('build', {
...BASE_OPTIONS,

View File

@ -224,7 +224,7 @@ export async function execute(
module: {
rules: [
{
test: /\.(css|scss|sass|styl|less)$/,
test: /\.(css|scss|sass|less)$/,
loader: require.resolve('./empty-loader'),
},
],

View File

@ -76,7 +76,7 @@
"input": {
"type": "string",
"description": "The file to include.",
"pattern": "\\.(?:css|scss|sass|less|styl)$"
"pattern": "\\.(?:css|scss|sass|less)$"
},
"bundleName": {
"type": "string",
@ -95,7 +95,7 @@
{
"type": "string",
"description": "The file to include.",
"pattern": "\\.(?:css|scss|sass|less|styl)$"
"pattern": "\\.(?:css|scss|sass|less)$"
}
]
}

View File

@ -101,13 +101,6 @@ export function getStylesConfig(wco: WebpackConfigOptions): Configuration {
extraPlugins.push(new RemoveHashPlugin({ chunkNames: noInjectNames, hashFormat }));
}
if (globalStylePaths.some((p) => p.endsWith('.styl'))) {
wco.logger.warn(
'Stylus usage is deprecated and will be removed in a future major version. ' +
'To opt-out of the deprecated behaviour, please migrate to another stylesheet language.',
);
}
const sassImplementation = new SassWorkerImplementation();
const sassTildeUsageMessage = new Set<string>();
@ -366,22 +359,6 @@ export function getStylesConfig(wco: WebpackConfigOptions): Configuration {
},
],
},
{
extensions: ['styl'],
use: [
{
loader: require.resolve('stylus-loader'),
options: {
sourceMap: cssSourceMap,
stylusOptions: {
compress: false,
sourceMap: { comment: false },
paths: includePaths,
},
},
},
],
},
];
return {

View File

@ -47,7 +47,7 @@ export class AnyComponentStyleBudgetChecker {
return;
}
const cssExtensions = ['.css', '.scss', '.less', '.styl', '.sass'];
const cssExtensions = ['.css', '.scss', '.less', '.sass'];
const componentStyles = Object.keys(compilation.assets)
.filter((name) => cssExtensions.includes(path.extname(name)))

View File

@ -52,7 +52,7 @@ export class CssOptimizerPlugin {
logger.time('optimize css assets');
for (const assetName of Object.keys(compilationAssets)) {
if (!/\.(?:css|scss|sass|less|styl)$/.test(assetName)) {
if (!/\.(?:css|scss|sass|less)$/.test(assetName)) {
continue;
}

View File

@ -18,17 +18,6 @@ export default async function () {
@import 'variables';
h2 { background-color: $primary-color; }
`,
'src/style-paths/variables.styl': '$primary-color = green',
'src/styles.styl': `
@import 'variables'
h3
color: $primary-color
`,
'src/app/app.component.styl': `
@import 'variables'
h4
background-color: $primary-color
`,
'src/style-paths/variables.less': '@primary-color: #ADDADD;',
'src/styles.less': `
@import 'variables';
@ -43,17 +32,14 @@ export default async function () {
await replaceInFile(
'src/app/app.component.ts',
`'./app.component.css\'`,
`'./app.component.scss'` + (esbuild ? '' : `, './app.component.styl', './app.component.less'`),
`'./app.component.scss'` + (esbuild ? '' : `, './app.component.less'`),
);
await updateJsonFile('angular.json', (workspaceJson) => {
const appArchitect = workspaceJson.projects['test-project'].architect;
appArchitect.build.options.styles = [{ input: 'src/styles.scss' }];
if (!esbuild) {
appArchitect.build.options.styles.push(
{ input: 'src/styles.styl' },
{ input: 'src/styles.less' },
);
appArchitect.build.options.styles.push({ input: 'src/styles.less' });
}
appArchitect.build.options.stylePreprocessorOptions = {
includePaths: ['src/style-paths'],
@ -64,9 +50,7 @@ export default async function () {
await expectFileToMatch('dist/test-project/styles.css', /h1\s*{\s*color: red;\s*}/);
await expectFileToMatch('dist/test-project/main.js', /h2.*{.*color: red;.*}/);
if (!esbuild) {
// These checks are for the less and stylus files
await expectFileToMatch('dist/test-project/styles.css', /h3\s*{\s*color: #008000;\s*}/);
await expectFileToMatch('dist/test-project/main.js', /h4.*{.*color: #008000;.*}/);
// These checks are for the less files
await expectFileToMatch('dist/test-project/styles.css', /h5\s*{\s*color: #ADDADD;\s*}/);
await expectFileToMatch('dist/test-project/main.js', /h6.*{.*color: #ADDADD;.*}/);
}
@ -77,8 +61,6 @@ export default async function () {
await expectFileToMatch('dist/test-project/styles.css', /h1\s*{\s*color: red;\s*}/);
await expectFileToMatch('dist/test-project/main.js', /h2.*{.*color: red;.*}/);
await expectFileToMatch('dist/test-project/styles.css', /h3\s*{\s*color: #008000;\s*}/);
await expectFileToMatch('dist/test-project/main.js', /h4.*{.*color: #008000;.*}/);
await expectFileToMatch('dist/test-project/styles.css', /h5\s*{\s*color: #ADDADD;\s*}/);
await expectFileToMatch('dist/test-project/main.js', /h6.*{.*color: #ADDADD;.*}/);
}

View File

@ -1,51 +0,0 @@
import {
writeMultipleFiles,
deleteFile,
expectFileToMatch,
replaceInFile,
} from '../../../utils/fs';
import { expectToFail } from '../../../utils/utils';
import { ng } from '../../../utils/process';
import { updateJsonFile } from '../../../utils/project';
export default function () {
// TODO(architect): Delete this test. It is now in devkit/build-angular.
return writeMultipleFiles({
'src/styles.styl': `
@import './imported-styles.styl';
body { background-color: blue; }
`,
'src/imported-styles.styl': 'p { background-color: red; }',
'src/app/app.component.styl': `
.outer {
.inner {
background: #fff;
}
}
`,
})
.then(() => deleteFile('src/app/app.component.css'))
.then(() =>
updateJsonFile('angular.json', (workspaceJson) => {
const appArchitect = workspaceJson.projects['test-project'].architect;
appArchitect.build.options.styles = [{ input: 'src/styles.styl' }];
}),
)
.then(() =>
replaceInFile('src/app/app.component.ts', './app.component.css', './app.component.styl'),
)
.then(() => ng('build', '--source-map', '--configuration=development'))
.then(() =>
expectFileToMatch('dist/test-project/styles.css', /body\s*{\s*background-color: #00f;\s*}/),
)
.then(() =>
expectFileToMatch('dist/test-project/styles.css', /p\s*{\s*background-color: #f00;\s*}/),
)
.then(() =>
expectToFail(() => expectFileToMatch('dist/test-project/styles.css', '"mappings":""')),
)
.then(() =>
expectFileToMatch('dist/test-project/main.js', /.outer.*.inner.*background:\s*#[fF]+/),
);
}