Skip to content

Commit 7d715fe

Browse files
committed
feat: jest-less-loader
0 parents  commit 7d715fe

15 files changed

+385
-0
lines changed

.commitlintrc.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports = {
2+
rules: {
3+
'type-enum': [
4+
2,
5+
'always',
6+
['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test', 'wip'],
7+
],
8+
},
9+
};

.eslintrc

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"parser": "@typescript-eslint/parser",
3+
"parserOptions": {
4+
"project": "./tsconfig.ci.json"
5+
},
6+
"plugins": ["@typescript-eslint"],
7+
"extends": [
8+
"eslint:recommended",
9+
"plugin:@typescript-eslint/eslint-recommended",
10+
"plugin:@typescript-eslint/recommended",
11+
"prettier",
12+
"prettier/@typescript-eslint"
13+
],
14+
"rules": {
15+
"@typescript-eslint/ban-ts-ignore": 0
16+
}
17+
}

.github/FUNDING.yml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# These are supported funding model platforms
2+
3+
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4+
patreon: # Replace with a single Patreon username
5+
open_collective: # Replace with a single Open Collective username
6+
ko_fi: # Replace with a single Ko-fi username
7+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9+
liberapay: # Replace with a single Liberapay username
10+
issuehunt: # Replace with a single IssueHunt username
11+
otechie: # Replace with a single Otechie username
12+
custom: ['https://paypal.me/hustcc', 'https://atool.vip']

.github/workflows/build.yml

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: build
2+
3+
on: [push]
4+
5+
jobs:
6+
build:
7+
8+
runs-on: macOS-latest
9+
10+
strategy:
11+
matrix:
12+
node-version: [8.x, 10.x, 12.x]
13+
14+
steps:
15+
- uses: actions/checkout@v1
16+
- name: Use Node.js ${{ matrix.node-version }}
17+
uses: actions/setup-node@v1
18+
with:
19+
node-version: ${{ matrix.node-version }}
20+
- name: ci
21+
run: |
22+
npm install
23+
npm run build
24+
npm run ci
25+
- name: coverall
26+
if: success()
27+
uses: coverallsapp/github-action@master
28+
with:
29+
github-token: ${{ secrets.GITHUB_TOKEN }}

.gitignore

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
lerna-debug.log*
8+
9+
# Sys
10+
.DS_STORE
11+
.idea
12+
13+
# Node
14+
node_modules/
15+
16+
# Build
17+
dist
18+
lib
19+
esm
20+
21+
# Test
22+
coverage

.prettierrc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"semi": true,
3+
"singleQuote": true,
4+
"trailingComma": "all",
5+
"bracketSpacing": true,
6+
"printWidth": 120,
7+
"arrowParens": "always"
8+
}

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 hustcc
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# jest-less-loader
2+
3+
> Jest transformer to run `.less` file in [jest-electron](https://github.com/hustcc/jest-electron) or in node env.
4+
5+
6+
[![npm Version](https://img.shields.io/npm/v/jest-less-loader.svg)](https://www.npmjs.com/package/jest-less-loader)
7+
[![Build Status](https://github.com/hustcc/jest-less-loader/workflows/build/badge.svg)](https://github.com/hustcc/jest-less-loader/actions)
8+
[![Coverage Status](https://coveralls.io/repos/github/hustcc/jest-less-loader/badge.svg)](https://coveralls.io/github/hustcc/jest-less-loader)
9+
[![npm License](https://img.shields.io/npm/l/jest-less-loader.svg)](https://www.npmjs.com/package/jest-less-loader)
10+
11+
12+
13+
## Usage
14+
15+
16+
- Install
17+
18+
```bash
19+
$ npm i --save-dev jest-less-loader
20+
```
21+
22+
- Configure
23+
24+
Update your jest configure, and add it into transform.
25+
26+
```diff
27+
+ "transform": {
28+
+ ".+\\.less$": "jest-less-loader"
29+
+ },
30+
```
31+
32+
33+
34+
## License
35+
36+
MIT@[hustcc](https://github.com/hustcc).

__tests__/electron.spec.ts

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// @ts-ignore
2+
import transformer from '../src';
3+
import './index.less';
4+
5+
describe('jest-less-loader', () => {
6+
test('import less', () => {
7+
expect(document.querySelectorAll('style')[0].innerHTML).toContain('background: red;');
8+
});
9+
10+
test('transformer success', () => {
11+
const less = `
12+
html {
13+
body {
14+
background: green;
15+
}
16+
}
17+
`;
18+
19+
expect(transformer.process(less).code).toEqual('');
20+
expect(document.querySelectorAll('style')[1].innerHTML).toContain('background: green;');
21+
});
22+
23+
test('transformer less syntax', () => {
24+
const less = `
25+
html {
26+
body {
27+
background;
28+
}
29+
}
30+
`;
31+
32+
expect(() => transformer.process(less)).toThrow();
33+
});
34+
});

__tests__/index.less

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
html {
2+
body {
3+
background: red;
4+
}
5+
}

__tests__/node.spec.ts

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// @ts-ignore
2+
import transformer from '../src';
3+
import './index.less';
4+
5+
describe('jest-less-loader', () => {
6+
test('transformer success', () => {
7+
const less = `
8+
html {
9+
body {
10+
background: green;
11+
}
12+
}
13+
`;
14+
15+
expect(transformer.process(less).code).toEqual('');
16+
});
17+
18+
test('transformer less syntax', () => {
19+
const less = `
20+
html {
21+
body {
22+
background;
23+
}
24+
}
25+
`;
26+
27+
expect(() => transformer.process(less)).toThrow();
28+
});
29+
});

package.json

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{
2+
"name": "jest-less-loader",
3+
"version": "0.1.0",
4+
"description": "Jest transformer for .less file.",
5+
"license": "MIT",
6+
"main": "lib/index.js",
7+
"files": [
8+
"lib"
9+
],
10+
"scripts": {
11+
"clean": "rimraf -rf lib",
12+
"lint": "eslint src/**/*.ts __tests__/**/*.ts",
13+
"lint-staged": "lint-staged",
14+
"test": "jest",
15+
"ci": "npm run lint && npm run test && lint-md .",
16+
"start": "tsc -w",
17+
"build": "rimraf ./lib && tsc --module commonjs --outDir lib",
18+
"prepublishOnly": "npm run build"
19+
},
20+
"dependencies": {},
21+
"peerDependencies": {
22+
"less": "^3.10.3"
23+
},
24+
"keywords": [
25+
"jest",
26+
"less",
27+
"transformer"
28+
],
29+
"devDependencies": {
30+
"@commitlint/cli": "^8.2.0",
31+
"@types/jest": "^24.0.18",
32+
"@types/node": "^12.12.14",
33+
"@typescript-eslint/eslint-plugin": "^2.3.1",
34+
"@typescript-eslint/parser": "^2.3.1",
35+
"eslint": "^6.4.0",
36+
"eslint-config-prettier": "^6.3.0",
37+
"husky": "^3.0.5",
38+
"jest": "^24.9.0",
39+
"jest-electron": "^0.1.7",
40+
"less": "^3.10.3",
41+
"lint-md-cli": "^0.1.1",
42+
"lint-staged": "^9.3.0",
43+
"prettier": "^1.18.2",
44+
"rimraf": "^3.0.0",
45+
"ts-jest": "^24.1.0",
46+
"typescript": "^3.6.3"
47+
},
48+
"jest": {
49+
"runner": "jest-electron/runner",
50+
"testEnvironment": "jest-electron/environment",
51+
"preset": "ts-jest",
52+
"collectCoverage": true,
53+
"testRegex": "(/__tests__/.*\\.(test|spec))\\.ts$",
54+
"collectCoverageFrom": [
55+
"src/**/*.ts"
56+
],
57+
"transform": {
58+
".+\\.less$": "./lib/index.js"
59+
}
60+
},
61+
"lint-staged": {
62+
"*.{ts,tsx}": [
63+
"eslint --fix",
64+
"prettier --write",
65+
"git add"
66+
]
67+
},
68+
"husky": {
69+
"hooks": {
70+
"pre-commit": "npm run lint-staged",
71+
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
72+
}
73+
}
74+
}

src/index.ts

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import less from 'less';
2+
3+
interface TransformerResult {
4+
readonly code: string;
5+
}
6+
7+
interface Transformer {
8+
process: (fileContent: string) => TransformerResult;
9+
}
10+
11+
/**
12+
* transform less sync
13+
* @param content
14+
*/
15+
function transformLess(content: string): string {
16+
const data = content.replace(/^\uFEFF/, '');
17+
18+
const options = { sync: true };
19+
20+
let css = '';
21+
22+
less.render(data, options, function(err, result) {
23+
if (err) throw err;
24+
css = result.css;
25+
});
26+
27+
return css;
28+
}
29+
30+
/**
31+
* inject style css into header
32+
* @param css
33+
*/
34+
function injectStyle(css: string): void {
35+
const head = document.getElementsByTagName('head')[0];
36+
37+
const style = document.createElement('style');
38+
style.type = 'text/css';
39+
style.appendChild(document.createTextNode(css));
40+
41+
head.appendChild(style);
42+
}
43+
44+
/**
45+
* the transformer entry
46+
* @type {{process(*=): *}}
47+
*/
48+
module.exports = {
49+
process(fileContent): object {
50+
const css = transformLess(fileContent);
51+
52+
// when running in nodejs env, will throw error.
53+
try {
54+
injectStyle(css);
55+
} catch (e) {
56+
// do nothing
57+
}
58+
59+
// no code for js module
60+
return {
61+
code: '',
62+
};
63+
},
64+
} as Transformer;

tsconfig.ci.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"include": ["src/**/*", "__tests__/**/*"]
4+
}

tsconfig.json

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"compilerOptions": {
3+
"outDir": "lib",
4+
"module": "commonjs",
5+
"target": "es5",
6+
"jsx": "preserve",
7+
"moduleResolution": "node",
8+
"experimentalDecorators": true,
9+
"declaration": true,
10+
"sourceMap": true,
11+
"allowSyntheticDefaultImports": true,
12+
"esModuleInterop": true,
13+
"pretty": true,
14+
"lib": ["dom", "esnext"],
15+
"skipLibCheck": true,
16+
"sourceRoot": "src",
17+
"baseUrl": "src"
18+
},
19+
"include": ["src/**/*"],
20+
"exclude": ["node_modules"]
21+
}

0 commit comments

Comments
 (0)