Skip to content

update: addLessLoader #185

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

Merged
merged 16 commits into from
Nov 22, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
@@ -153,6 +153,16 @@
"contributions": [
"code"
]
},
{
"login": "onlyling",
"name": "LING_ZI_QING",
"avatar_url": "https://avatars3.githubusercontent.com/u/9999765?v=4",
"profile": "https://www.onlyling.com",
"contributions": [
"code",
"doc"
]
}
],
"contributorsPerLine": 7
14 changes: 9 additions & 5 deletions api.md
Original file line number Diff line number Diff line change
@@ -362,15 +362,13 @@ adjustWorkbox(wb =>
First, install `less` and `less-loader` packages:

```bash
yarn add less
yarn add --dev less-loader
yarn add --dev less less-loader
```

or:

```bash
npm i less
npm i -D less-loader
npm i -D less less-loader
```

After it's done, call `addLessLoader` in `override` like below:
@@ -390,7 +388,13 @@ module.exports = override(
addLessLoader({
strictMath: true,
noIeCompat: true,
localIdentName: "[local]--[hash:base64:5]" // if you use CSS Modules, and custom `localIdentName`, default is '[local]--[hash:base64:5]'.
modifyVars: {
"@primary-color": "#1DA57A", // for example, you use Ant Design to change theme color.
},
cssLoaderOptions: {}, // .less file used css-loader option, not all CSS file.
cssModules: {
localIdentName: "[path][name]__[local]--[hash:base64:5]", // if you use CSS Modules, and custom `localIdentName`, default is '[local]--[hash:base64:5]'.
},
})
);
```
3 changes: 2 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# `customize-cra`

[![All Contributors](https://img.shields.io/badge/all_contributors-16-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-17-orange.svg?style=flat-square)](#contributors-)

This project provides a set of utilities to customize [`create-react-app`](https://github.com/facebook/create-react-app) versions 2 and 3 configurations leveraging [`react-app-rewired`](https://github.com/timarney/react-app-rewired/) core functionalities.

@@ -147,6 +147,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<tr>
<td align="center"><a href="https://github.com/billypon"><img src="https://avatars2.githubusercontent.com/u/1763302?v=4" width="100px;" alt="billypon"/><br /><sub><b>billypon</b></sub></a><br /><a href="https://github.com/arackaf/customize-cra/commits?author=billypon" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/1123612483"><img src="https://avatars1.githubusercontent.com/u/20741541?v=4" width="100px;" alt="Juetta"/><br /><sub><b>Juetta</b></sub></a><br /><a href="https://github.com/arackaf/customize-cra/commits?author=1123612483" title="Code">💻</a></td>
<td align="center"><a href="https://www.onlyling.com"><img src="https://avatars3.githubusercontent.com/u/9999765?v=4" width="100px;" alt="LING_ZI_QING"/><br /><sub><b>LING_ZI_QING</b></sub></a><br /><a href="https://github.com/arackaf/customize-cra/commits?author=onlyling" title="Code">💻</a> <a href="https://github.com/arackaf/customize-cra/commits?author=onlyling" title="Documentation">📖</a></td>
</tr>
</table>

109 changes: 71 additions & 38 deletions src/customizers/webpack.js
Original file line number Diff line number Diff line change
@@ -119,29 +119,32 @@ export const enableEslintTypescript = () => config => {
};

export const addLessLoader = (loaderOptions = {}) => config => {
const mode = process.env.NODE_ENV === "development" ? "dev" : "prod";
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const postcssNormalize = require("postcss-normalize");

// Need these for production mode, which are copied from react-scripts
const publicPath = require("react-scripts/config/paths").servedPath;
const shouldUseRelativeAssetPaths = publicPath === "./";
const shouldUseSourceMap =
mode === "prod" && process.env.GENERATE_SOURCEMAP !== "false";
const cssLoaderOptions = loaderOptions.cssLoaderOptions || {};
const cssModules = loaderOptions.cssModules || {
localIdentName: "[local]--[hash:base64:5]"
};
const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/;
const localIdentName =
loaderOptions.localIdentName || "[path][name]__[local]--[hash:base64:5]";

const getLessLoader = cssOptions => {
return [
mode === "dev"
? require.resolve("style-loader")
: {
loader: require("mini-css-extract-plugin").loader,
options: Object.assign(
{},
shouldUseRelativeAssetPaths ? { publicPath: "../../" } : undefined
)
},

const webpackEnv = process.env.NODE_ENV;
const isEnvDevelopment = webpackEnv === "development";
const isEnvProduction = webpackEnv === "production";
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false";
const publicPath = config.output.publicPath;
const shouldUseRelativeAssetPaths = publicPath === "./";

// copy from react-scripts
// https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/webpack.config.js#L93
const getStyleLoaders = (cssOptions, preProcessor) => {
const loaders = [
isEnvDevelopment && require.resolve("style-loader"),
isEnvProduction && {
loader: MiniCssExtractPlugin.loader,
options: shouldUseRelativeAssetPaths ? { publicPath: "../../" } : {}
},
{
loader: require.resolve("css-loader"),
options: cssOptions
@@ -157,18 +160,34 @@ export const addLessLoader = (loaderOptions = {}) => config => {
flexbox: "no-2009"
},
stage: 3
})
}),
postcssNormalize()
],
sourceMap: shouldUseSourceMap
sourceMap: isEnvProduction && shouldUseSourceMap
}
},
{
loader: require.resolve("less-loader"),
options: Object.assign(loaderOptions, {
source: shouldUseSourceMap
})
}
];
].filter(Boolean);
if (preProcessor) {
loaders.push(
{
loader: require.resolve("resolve-url-loader"),
options: {
sourceMap: isEnvProduction && shouldUseSourceMap
}
},
{
loader: require.resolve(preProcessor),
// not the same as react-scripts
options: Object.assign(
{
sourceMap: true
},
loaderOptions
)
}
);
}
return loaders;
};

const loaders = config.module.rules.find(rule => Array.isArray(rule.oneOf))
@@ -181,18 +200,32 @@ export const addLessLoader = (loaderOptions = {}) => config => {
{
test: lessRegex,
exclude: lessModuleRegex,
use: getLessLoader({
importLoaders: 2
}),
sideEffects: mode === "prod"
use: getStyleLoaders(
Object.assign(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap
},
cssLoaderOptions
),
"less-loader"
)
},
{
test: lessModuleRegex,
use: getLessLoader({
importLoaders: 2,
modules: true,
localIdentName: localIdentName
})
use: getStyleLoaders(
Object.assign(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap
},
cssLoaderOptions,
{
modules: cssModules
}
),
"less-loader"
)
}
);