@best-shot/preset-style 0.8.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # @best-shot/preset-style <img src="https://cdn.jsdelivr.net/gh/best-shot/best-shot/packages/core/logo.svg" alt="logo" height="80" align="right">
2
+
3
+ A `best-shot` preset for stylesheet.
4
+
5
+ [![npm][npm-badge]][npm-url]
6
+ [![github][github-badge]][github-url]
7
+ ![node][node-badge]
8
+
9
+ [npm-url]: https://www.npmjs.com/package/@best-shot/preset-style
10
+ [npm-badge]: https://img.shields.io/npm/v/@best-shot/preset-style.svg?style=flat-square&logo=npm
11
+ [github-url]: https://github.com/best-shot/best-shot/tree/master/packages/preset-style
12
+ [github-badge]: https://img.shields.io/npm/l/@best-shot/preset-style.svg?style=flat-square&colorB=blue&logo=github
13
+ [node-badge]: https://img.shields.io/node/v/@best-shot/preset-style.svg?style=flat-square&colorB=green&logo=node.js
14
+
15
+ This preset offer the following features:
16
+
17
+ - [CSS Modules] support
18
+ - [Less] / [Sass] syntax support
19
+ - [PostCSS] support
20
+ - Use [postcss-preset-evergreen] by default
21
+ - Use [cssnano] in production mode
22
+
23
+ [css modules]: https://github.com/css-modules/css-modules
24
+ [cssnano]: https://cssnano.co/
25
+ [sass]: https://sass-lang.com/
26
+ [less]: http://lesscss.org/
27
+ [postcss]: https://github.com/postcss/postcss
28
+ [postcss-preset-evergreen]: https://github.com/best-shot/postcss-preset-evergreen
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ npm install @best-shot/preset-style --save-dev
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ ```mjs
39
+ // example: .best-shot/config.mjs
40
+ export default {
41
+ presets: ['style']
42
+ };
43
+ ```
44
+
45
+ ### CSS Modules support
46
+
47
+ Use `[name].module.[extname]` as filename.
48
+
49
+ ```js
50
+ import { foo } from './foo.module.css';
51
+ import { bar } from './bar.module.scss';
52
+ ```
53
+
54
+ Use CSS Modules in Vue.js. [Learn more](https://vue-loader.vuejs.org/guide/css-modules.html)
55
+
56
+ <!-- eslint-skip -->
57
+
58
+ ```vue
59
+ <!-- example.vue -->
60
+ <style lang="css" module></style>
61
+ <style lang="scss" module></style>
62
+ <style lang="less" module></style>
63
+ ```
64
+
65
+ ## Tips
66
+
67
+ ### Load custom `postcss` config
68
+
69
+ Disable internal options:
70
+
71
+ ```mjs
72
+ // example: .best-shot/config.mjs
73
+ export default {
74
+ webpackChain(config) {
75
+ config.module
76
+ .rule('style')
77
+ .rule('postcss')
78
+ .use('postcss-loader')
79
+ .tap((options) => ({
80
+ ...options,
81
+ postcssOptions: {}
82
+ }));
83
+ }
84
+ };
85
+ ```
86
+
87
+ Write your config in any way. See <https://github.com/postcss/postcss-load-config>
88
+
89
+ ```cjs
90
+ // example: postcss.config.cjs
91
+ module.exports = {
92
+ plugins: {
93
+ 'postcss-preset-env': {}
94
+ }
95
+ };
96
+ ```
97
+
98
+ ## Related
99
+
100
+ - [@best-shot/preset-asset](../preset-asset)
101
+ - [@best-shot/preset-web](../preset-web)
102
+ - [@best-shot/core](../core)
package/index.cjs ADDED
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ const { relative } = require('path');
4
+
5
+ const applyScssLess = require('./lib/apply-scss-less.cjs');
6
+ const applyStylesheet = require('./lib/apply-stylesheet.cjs');
7
+
8
+ exports.apply = function applyStyle({
9
+ config: { less, asset: { esModule = true } = {} },
10
+ }) {
11
+ return (chain) => {
12
+ const context = chain.get('context');
13
+
14
+ chain.batch(applyStylesheet(esModule)).batch(applyScssLess(less));
15
+
16
+ chain.resolveLoader.modules.prepend(relative(context, module.paths[0]));
17
+ };
18
+ };
19
+
20
+ exports.schema = {
21
+ less: {
22
+ type: 'object',
23
+ },
24
+ asset: {
25
+ type: 'object',
26
+ default: {},
27
+ properties: {
28
+ esModule: {
29
+ type: 'boolean',
30
+ default: true,
31
+ },
32
+ },
33
+ },
34
+ };
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+
3
+ const extToRegexp = require('ext-to-regexp');
4
+
5
+ function addExtname(rule) {
6
+ const regexp = rule.get('test');
7
+ rule.test(regexp.add('scss', 'sass', 'less'));
8
+ }
9
+
10
+ module.exports = function applyScssLess(less) {
11
+ return (chain) => {
12
+ chain.module.rule('style').batch(addExtname);
13
+
14
+ chain.module
15
+ .rule('sass')
16
+ .test(extToRegexp({ extname: ['scss', 'sass'] }))
17
+ .use('resolve-url-loader')
18
+ .loader('resolve-url-loader')
19
+ .options({
20
+ sourceMap: !['eval', false].includes(chain.get('devtool')),
21
+ removeCR: true,
22
+ })
23
+ .end()
24
+ .use('sass-loader')
25
+ .loader('sass-loader')
26
+ .options({
27
+ sourceMap: true,
28
+ });
29
+
30
+ chain.module
31
+ .rule('less')
32
+ .test(extToRegexp({ extname: ['less'] }))
33
+ .use('less-loader')
34
+ .loader('less-loader')
35
+ .options({
36
+ lessOptions: {
37
+ rewriteUrls: 'local',
38
+ ...less,
39
+ },
40
+ });
41
+ };
42
+ };
@@ -0,0 +1,113 @@
1
+ 'use strict';
2
+
3
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
4
+ const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
5
+ const extToRegexp = require('ext-to-regexp');
6
+ const slashToRegexp = require('slash-to-regexp');
7
+
8
+ function applyOneOf({ auto = false, esModule = true, mode }) {
9
+ return (rule) => {
10
+ rule
11
+ .use('css-loader')
12
+ .loader('css-loader')
13
+ .options({
14
+ ...(!esModule ? { esModule: false } : undefined),
15
+ importLoaders: 3,
16
+ modules: {
17
+ ...(auto ? { auto } : undefined),
18
+ ...(esModule
19
+ ? { namedExport: true }
20
+ : { exportLocalsConvention: 'camelCaseOnly' }),
21
+ localIdentName: {
22
+ development: '[path][name]__[local]',
23
+ production: '[local]_[hash:base64:8]',
24
+ }[mode],
25
+ },
26
+ });
27
+ };
28
+ }
29
+
30
+ module.exports = function applyStylesheet(esModule = true) {
31
+ return (chain) => {
32
+ chain.resolve.extensions.add('.css');
33
+
34
+ const minimize = chain.optimization.get('minimize');
35
+
36
+ if (minimize) {
37
+ chain.optimization.minimizer('css-minimizer').use(CssMinimizerPlugin, [
38
+ {
39
+ minimizerOptions: {
40
+ preset: ['default', { discardComments: { removeAll: true } }],
41
+ },
42
+ },
43
+ ]);
44
+ }
45
+
46
+ chain.module.rule('style').test(extToRegexp({ extname: ['css'] }));
47
+
48
+ const mode = chain.get('mode');
49
+ const useHot = chain.devServer.get('hot') || false;
50
+
51
+ const parent = chain.module.rule('style').rule('css');
52
+
53
+ parent
54
+ .oneOf('css-modules-by-query')
55
+ .resourceQuery(/module/)
56
+ .batch(applyOneOf({ mode, esModule }));
57
+
58
+ parent
59
+ .oneOf('css-modules-by-filename')
60
+ .batch(applyOneOf({ mode, esModule, auto: true }));
61
+
62
+ chain.module
63
+ .rule('style')
64
+ .rule('postcss')
65
+ .use('postcss-loader')
66
+ .loader('postcss-loader')
67
+ .options({
68
+ postcssOptions: {
69
+ plugins: ['postcss-preset-evergreen'],
70
+ },
71
+ });
72
+
73
+ const extract = !useHot;
74
+
75
+ if (chain.module.rules.has('babel')) {
76
+ chain.module
77
+ .rule('babel')
78
+ .exclude.add(slashToRegexp('/node_modules/css-loader/'))
79
+ .when(extract, (exclude) =>
80
+ exclude.add(slashToRegexp('/node_modules/mini-css-extract-plugin/')),
81
+ );
82
+ }
83
+
84
+ if (extract) {
85
+ chain.plugin('extract-css').use(MiniCssExtractPlugin, [
86
+ {
87
+ filename: '[name].css',
88
+ // chunkFilename: '[id].css',
89
+ ignoreOrder: true,
90
+ },
91
+ ]);
92
+ }
93
+
94
+ function takeOptions(loader) {
95
+ if (!esModule) {
96
+ loader.options({ esModule: false });
97
+ }
98
+ }
99
+
100
+ chain.module.rule('style').when(
101
+ extract,
102
+ (rule) => {
103
+ rule
104
+ .use('extract-css')
105
+ .loader(MiniCssExtractPlugin.loader)
106
+ .batch(takeOptions);
107
+ },
108
+ (rule) => {
109
+ rule.use('style-loader').loader('style-loader').batch(takeOptions);
110
+ },
111
+ );
112
+ };
113
+ };
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@best-shot/preset-style",
3
+ "version": "0.8.8",
4
+ "description": "A `best-shot` preset for stylesheet",
5
+ "license": "MIT",
6
+ "author": {
7
+ "name": "Eric Chen",
8
+ "email": "airkro@qq.com"
9
+ },
10
+ "keywords": [
11
+ "autoprefixer",
12
+ "best-shot",
13
+ "css",
14
+ "css-modules",
15
+ "cssnano",
16
+ "cssnext",
17
+ "evergreen",
18
+ "less",
19
+ "modules",
20
+ "postcss",
21
+ "sass",
22
+ "scss",
23
+ "style",
24
+ "webpack"
25
+ ],
26
+ "homepage": "https://github.com/best-shot/best-shot/tree/master/packages/preset-style",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/best-shot/best-shot.git",
30
+ "directory": "packages/preset-style"
31
+ },
32
+ "bugs": {
33
+ "url": "https://github.com/best-shot/best-shot/issues"
34
+ },
35
+ "main": "index.cjs",
36
+ "dependencies": {
37
+ "css-loader": "^6.3.0",
38
+ "css-minimizer-webpack-plugin": "^3.0.2",
39
+ "cssnano": "^5.0.8",
40
+ "ext-to-regexp": "^0.1.0",
41
+ "less": "^4.1.1",
42
+ "less-loader": "^10.0.1",
43
+ "mini-css-extract-plugin": "^2.3.0",
44
+ "postcss": "^8.3.6",
45
+ "postcss-loader": "^6.1.1",
46
+ "postcss-preset-evergreen": "^0.2.1",
47
+ "resolve-url-loader": "^4.0.0",
48
+ "sass": "^1.42.0",
49
+ "sass-loader": "^12.1.0",
50
+ "slash-to-regexp": "^0.0.4",
51
+ "style-loader": "^3.3.0"
52
+ },
53
+ "peerDependencies": {
54
+ "@best-shot/core": "^0.5.1"
55
+ },
56
+ "engines": {
57
+ "node": "^12.22.0 || ^14.17.0"
58
+ },
59
+ "publishConfig": {
60
+ "access": "public",
61
+ "registry": "https://registry.npmjs.org/"
62
+ },
63
+ "x-readme": {
64
+ "logo": "https://cdn.jsdelivr.net/gh/best-shot/best-shot/packages/core/logo.svg"
65
+ }
66
+ }