Skip to content

Commit

Permalink
feat: Support patterns relative to webpack context
Browse files Browse the repository at this point in the history
  • Loading branch information
yenshih committed Jul 12, 2019
1 parent a64f796 commit 3e9a3ca
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 76 deletions.
11 changes: 5 additions & 6 deletions README.md
Expand Up @@ -3,6 +3,7 @@
[![downloads][downloads]][downloads-url]
[![build][build]][build-url]
[![coverage][coverage]][coverage-url]
[![996.icu][996.icu]][996.icu-url]

<div align="center">
<a href="https://github.com/webpack/webpack">
Expand Down Expand Up @@ -150,13 +151,9 @@ Only supports `.css` `.sass` `.scss` `.less` `.styl` as resources file extension

An optional function which controls the resources injection precisely. It also supports `'prepend'` and `'append'` for convenience, which means the loader will prepend or append all resources to source files, respectively.

It defaults to `'prepend'`, which implements as an injector function internally:
It defaults to `'prepend'`, which implements as an injector function internally.

```js
(source, resources) => resources.map(({content}) => content).join('') + source
```

Furthermore, an injector function should match type signature:
Furthermore, an injector function should match the following type signature:

```ts
(source: string, resources: StyleResource[]) => string | Promise<string>
Expand Down Expand Up @@ -206,3 +203,5 @@ You could disable this feature by setting `resolveUrl` to `false`.
[build-url]: https://travis-ci.org/yenshih/style-resources-loader
[coverage]: https://img.shields.io/coveralls/yenshih/style-resources-loader/master.svg?style=flat
[coverage-url]: https://coveralls.io/github/yenshih/style-resources-loader?branch=master
[996.icu]: https://img.shields.io/badge/link-996.icu-%23FF4D5B.svg?style=flat-square
[996.icu-url]: https://996.icu/#/en_US
89 changes: 45 additions & 44 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions package.json
Expand Up @@ -54,25 +54,25 @@
"@types/is-promise": "^2.1.0",
"@types/jest": "^24.0.15",
"@types/loader-utils": "^1.1.3",
"@types/node": "^12.0.10",
"@types/node": "^12.6.2",
"@types/webpack": "^4.4.34",
"@types/webpack-merge": "^4.1.5",
"@typescript-eslint/eslint-plugin": "^1.11.0",
"@typescript-eslint/parser": "^1.11.0",
"coveralls": "^3.0.4",
"coveralls": "^3.0.5",
"cross-env": "^5.2.0",
"eslint": "^6.0.1",
"eslint-config-prettier": "^6.0.0",
"eslint-plugin-import": "^2.18.0",
"eslint-plugin-prettier": "^3.1.0",
"husky": "^3.0.0",
"jest": "^24.8.0",
"lint-staged": "^9.0.2",
"lint-staged": "^9.2.0",
"prettier": "^1.18.2",
"raw-loader": "^3.0.0",
"ts-jest": "^24.0.2",
"typescript": "^3.5.2",
"webpack": "^4.35.2",
"typescript": "^3.5.3",
"webpack": "^4.35.3",
"webpack-merge": "^4.2.1"
},
"peerDependencies": {
Expand Down
14 changes: 9 additions & 5 deletions src/utils/getResources.ts
@@ -1,4 +1,5 @@
import fs from 'fs';
import path from 'path';
import util from 'util';

import glob from 'glob';
Expand All @@ -7,24 +8,27 @@ import {LoaderContext, StyleResource, StyleResources, StyleResourcesLoaderNormal

import {isStyleFile, resolveImportUrl} from '.';

const isLegacyWebpack = (ctx: any): ctx is {options: {context: string}} => !!ctx.options;

const getRootContext = (ctx: LoaderContext) => (isLegacyWebpack(ctx) ? ctx.options.context : ctx.rootContext);

const getResources = async function(ctx: LoaderContext, options: StyleResourcesLoaderNormalizedOptions) {
const {patterns, globOptions, resolveUrl} = options;

const resourceFragments = await Promise.all(
patterns
// We can change `map` to `flatMap` when `Array.prototype.flatMap` is fully supported.
.map(async pattern => {
const partialFiles = (await util.promisify(glob)(pattern, globOptions)).filter(isStyleFile);
const rootContext = getRootContext(ctx) || process.cwd();
const absolutePattern = path.isAbsolute(pattern) ? pattern : path.resolve(rootContext, pattern);
const partialFiles = (await util.promisify(glob)(absolutePattern, globOptions)).filter(isStyleFile);

partialFiles.forEach(ctx.dependency.bind(ctx));

const partialResources: StyleResources = await Promise.all(
partialFiles.map(async file => {
const content = await util.promisify(fs.readFile)(file, 'utf8');
const resource: StyleResource = {
file,
content,
};
const resource: StyleResource = {file, content};

return resolveUrl ? {file, content: resolveImportUrl(ctx, resource)} : resource;
}),
Expand Down
2 changes: 1 addition & 1 deletion src/utils/injectResources.ts
Expand Up @@ -16,7 +16,7 @@ const injectResources = async function(
const content = isPromise(dist) ? await dist : dist;

if (!isString(content)) {
throwValidationError('options.injector(...) returns a string', typeof content);
return throwValidationError('options.injector(...) returns a string', typeof content);
}

return content;
Expand Down
8 changes: 4 additions & 4 deletions src/utils/validateOptions.ts
Expand Up @@ -22,19 +22,19 @@ const valiateOptions = (options: any): options is StyleResourcesLoaderOptions =>
const {patterns, injector, globOptions, resolveUrl} = options;

if (!validatePatterns(patterns)) {
throwValidationError('options.patterns to be a string or an array of string', typeof patterns);
return throwValidationError('options.patterns to be a string or an array of string', typeof patterns);
}

if (!validateInjector(injector)) {
throwValidationError('options.injector to be a function or `prepend`, `append`', typeof injector);
return throwValidationError('options.injector to be a function or `prepend`, `append`', typeof injector);
}

if (!validateGlobOptions(globOptions)) {
throwValidationError('options.globOptions to be an object', typeof globOptions);
return throwValidationError('options.globOptions to be an object', typeof globOptions);
}

if (!validateResolveUrl(resolveUrl)) {
throwValidationError('options.resolveUrl to be a boolean', typeof resolveUrl);
return throwValidationError('options.resolveUrl to be a boolean', typeof resolveUrl);
}

return true;
Expand Down
5 changes: 3 additions & 2 deletions test/helpers/createBaseConfigOf.ts
Expand Up @@ -8,7 +8,8 @@ const createBaseConfigOf = (ext: StyleResourcesFileExt) => async (
testId: string,
isError: boolean = false,
): Promise<Configuration> => ({
entry: path.resolve(__dirname, `../${ext}/source.${ext}`),
context: path.resolve(__dirname, '..'),
entry: `./${ext}/source.${ext}`,
output: {
path: path.resolve(__dirname, `../${ext}/outputs`),
filename: `${testId}.js`,
Expand All @@ -22,7 +23,7 @@ const createBaseConfigOf = (ext: StyleResourcesFileExt) => async (
use: [
...(isError ? [] : ['raw-loader']),
{
loader: path.resolve(__dirname, '../../src/index.ts'),
loader: '../src/index.ts',
options: (await import(`../options/${testId}`)).default(ext),
},
],
Expand Down
7 changes: 1 addition & 6 deletions test/options/fileGlobbing.ts
@@ -1,10 +1,5 @@
import path from 'path';

import {StyleResourcesFileExt, StyleResourcesLoaderOptions} from '../../src';

export default (ext: StyleResourcesFileExt): StyleResourcesLoaderOptions => ({
patterns: [
path.resolve(__dirname, `../${ext}/variables/*.${ext}`),
path.resolve(__dirname, `../${ext}/mixins/*.${ext}`),
],
patterns: [`./${ext}/variables/*.${ext}`, `./${ext}/mixins/*.${ext}`],
});
4 changes: 1 addition & 3 deletions test/options/stringPattern.ts
@@ -1,7 +1,5 @@
import path from 'path';

import {StyleResourcesFileExt, StyleResourcesLoaderOptions} from '../../src';

export default (ext: StyleResourcesFileExt): StyleResourcesLoaderOptions => ({
patterns: path.resolve(__dirname, `../${ext}/resources.${ext}`),
patterns: `./${ext}/resources.${ext}`,
});

0 comments on commit 3e9a3ca

Please sign in to comment.