Skip to content

Commit c511acb

Browse files
authored
Merge pull request #40 from posthtml/options
v0.3.0
2 parents d4d8938 + 50debbb commit c511acb

7 files changed

Lines changed: 176 additions & 42 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10-
- Remove unhashed asset files, or require an "outDir" option
11-
1210
- Add optional files field to options parameter that matches specific file names
1311

1412
- Incorporate the `[hash:number]` format to specify the hash length
1513

14+
## [0.3.0](https://github.com/metonym/posthtml-hash/releases/tag/v0.3.0) - 2020-05-04
15+
16+
- Support omitting CSS/JS files to hash in `options`
17+
1618
## [0.2.3](https://github.com/metonym/posthtml-hash/releases/tag/v0.2.3) - 2019-12-27
1719

1820
- Fix bug by omitting an error if the file does not exist (e.g. external URL)

README.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
# posthtml-hash <img align="right" width="220" height="200" title="PostHTML logo" src="http://posthtml.github.io/posthtml/logo.svg">
22

33
[![NPM][npm]][npm-url]
4-
[![Build][build]][build-badge]
5-
[![Coverage][codecov-shield]][codecov]
64

75
`posthtml-hash` is a [PostHTML](https://github.com/posthtml/posthtml) plugin for hashing static CSS/JS assets to enable caching. [hasha](https://www.npmjs.com/package/hasha) is used to generate hashes.
86

@@ -59,13 +57,22 @@ posthtml()
5957
/**
6058
* Relative path to processed HTML file
6159
*/
62-
path: "public",
60+
path: "public", // default: ""
6361

6462
/**
6563
* Length of hash
66-
* Default is 20
6764
*/
68-
hashLength: 10,
65+
hashLength: 10, // default: 20
66+
67+
/**
68+
* Hash CSS files
69+
*/
70+
css: true, // default: true
71+
72+
/**
73+
* Hash JS files
74+
*/
75+
js: true, // default: true
6976
})
7077
)
7178
.process(html)
@@ -86,7 +93,3 @@ See the [PostHTML Guidelines](https://github.com/posthtml/posthtml/tree/master/d
8693

8794
[npm]: https://img.shields.io/npm/v/posthtml-hash.svg?color=blue
8895
[npm-url]: https://npmjs.com/package/posthtml-hash
89-
[build]: https://travis-ci.com/posthtml/posthtml-hash.svg?branch=master
90-
[build-badge]: https://travis-ci.com/posthtml/posthtml-hash
91-
[codecov]: https://codecov.io/gh/posthtml/posthtml-hash
92-
[codecov-shield]: https://img.shields.io/codecov/c/github/posthtml/posthtml-hash.svg

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "posthtml-hash",
3-
"version": "0.2.3",
3+
"version": "0.3.0",
44
"license": "MIT",
55
"description": "PostHTML plugin for hashing static assets",
66
"author": "Eric Liu (https://github.com/metonym)",

src/global.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
declare module "is-match";

src/plugin.ts

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,46 @@
1-
import fs from 'fs';
2-
import path from 'path';
3-
import { PostHTML } from 'posthtml';
4-
import { createHash, hashFileName, processFile } from './utils';
1+
import fs from "fs";
2+
import path from "path";
3+
import { PostHTML } from "posthtml";
4+
import { createHash, hashFileName, processFile } from "./utils";
55

6-
const DEFAULT_PATH = '';
6+
const DEFAULT_PATH = "";
77
const DEFAULT_HASH_LENGTH = 20;
88
const DEFAULT_OPTIONS: IOptions = {
99
path: DEFAULT_PATH,
10-
hashLength: DEFAULT_HASH_LENGTH
10+
hashLength: DEFAULT_HASH_LENGTH,
11+
css: true,
12+
js: true,
1113
};
1214

1315
function plugin(options = DEFAULT_OPTIONS) {
1416
return function posthtmlHash(tree: PostHTML.Node) {
17+
const hashLength = options.hashLength || DEFAULT_HASH_LENGTH;
18+
const css = options.css !== undefined ? options.css : DEFAULT_OPTIONS.css;
19+
const js = options.js !== undefined ? options.js : DEFAULT_OPTIONS.js;
1520
const nonEmptyString = new RegExp(/\S+/);
21+
const matchers = ([
22+
css && {
23+
tag: "link",
24+
attrs: { rel: "stylesheet", href: nonEmptyString },
25+
},
26+
js && { tag: "script", attrs: { src: nonEmptyString } },
27+
].filter(Boolean) as unknown) as IPostHTMLHashMatcher[];
1628

17-
const matchers: IPostHTMLHashMatcher[] = [
18-
{ tag: 'link', attrs: { rel: 'stylesheet', href: nonEmptyString } },
19-
{ tag: 'script', attrs: { src: nonEmptyString } }
20-
];
21-
22-
tree.match(matchers, node => {
29+
tree.match(matchers, (node) => {
2330
const attrs = node.attrs!;
24-
let fileName = '';
31+
let fileName = "";
2532

2633
if (attrs.href) {
2734
fileName = attrs.href;
2835
} else if (attrs.src) {
2936
fileName = attrs.src;
3037
}
3138

32-
const pathToFile = options.path || '';
39+
const pathToFile = options.path || "";
3340
const file = path.join(process.cwd(), pathToFile, fileName);
3441

3542
processFile(file, () => {
3643
const buffer = fs.readFileSync(file);
37-
const hashLength = options.hashLength || DEFAULT_HASH_LENGTH;
3844
const hash = createHash(buffer, hashLength);
3945
const hashedFileName = hashFileName(fileName, hash);
4046
const hashedFile = path.join(process.cwd(), pathToFile, hashedFileName);
@@ -56,6 +62,8 @@ function plugin(options = DEFAULT_OPTIONS) {
5662
interface IOptions {
5763
path?: string;
5864
hashLength?: number;
65+
css?: boolean;
66+
js?: boolean;
5967
}
6068

6169
interface IPostHTMLHashMatcher {

src/tests/__snapshots__/plugin.spec.ts.snap

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`posthtml-hash matches the snapshot – css only 1`] = `
4+
"
5+
<html>
6+
<head>
7+
<link rel=\\"stylesheet\\" href=\\"https://fonts.googleapis.com/css?family=Open+Sans:400,400i,600,600i,700,700i\\">
8+
<link rel=\\"stylesheet\\" href=\\"bundle.min.9a6cf95c41e87b9dc102.css\\">
9+
</head>
10+
<body>
11+
<script src=\\"bundle.min.js\\"></script>
12+
</body>
13+
</html>
14+
"
15+
`;
16+
317
exports[`posthtml-hash matches the snapshot – custom hash length 1`] = `
418
"
519
<html>
@@ -25,3 +39,31 @@ exports[`posthtml-hash matches the snapshot – default options 1`] = `
2539
</html>
2640
"
2741
`;
42+
43+
exports[`posthtml-hash matches the snapshot – js only 1`] = `
44+
"
45+
<html>
46+
<head>
47+
<link rel=\\"stylesheet\\" href=\\"https://fonts.googleapis.com/css?family=Open+Sans:400,400i,600,600i,700,700i\\">
48+
<link rel=\\"stylesheet\\" href=\\"bundle.min.css\\">
49+
</head>
50+
<body>
51+
<script src=\\"bundle.min.b0dcc67ffc1fd562f212.js\\"></script>
52+
</body>
53+
</html>
54+
"
55+
`;
56+
57+
exports[`posthtml-hash matches the snapshot – no hash 1`] = `
58+
"
59+
<html>
60+
<head>
61+
<link rel=\\"stylesheet\\" href=\\"https://fonts.googleapis.com/css?family=Open+Sans:400,400i,600,600i,700,700i\\">
62+
<link rel=\\"stylesheet\\" href=\\"bundle.min.css\\">
63+
</head>
64+
<body>
65+
<script src=\\"bundle.min.js\\"></script>
66+
</body>
67+
</html>
68+
"
69+
`;

src/tests/plugin.spec.ts

Lines changed: 93 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
1-
import fs from 'fs';
2-
import path from 'path';
3-
import posthtml from 'posthtml';
4-
import plugin from '../';
1+
import fs from "fs";
2+
import path from "path";
3+
import posthtml from "posthtml";
4+
import plugin from "../";
55

6-
describe('posthtml-hash', () => {
6+
describe("posthtml-hash", () => {
77
beforeEach(() => {
88
const folder = {
9-
input: '__fixtures__/original',
10-
output: '__fixtures__/processed'
9+
input: "__fixtures__/original",
10+
output: "__fixtures__/processed",
1111
};
1212

13-
copyFixture('bundle.min.css', folder);
14-
copyFixture('bundle.min.js', folder);
13+
copyFixture("bundle.min.css", folder);
14+
copyFixture("bundle.min.js", folder);
1515
});
1616

17-
it('matches the snapshot – default options', () => {
17+
it("matches the snapshot – css only", () => {
1818
posthtml()
19-
.use(plugin({ path: 'src/tests/__fixtures__/processed' }))
19+
.use(plugin({ path: "src/tests/__fixtures__/processed", js: false }))
2020
.process(
2121
`
2222
<html>
2323
<head>
24+
<link
25+
rel="stylesheet"
26+
href="https://fonts.googleapis.com/css?family=Open+Sans:400,400i,600,600i,700,700i"
27+
/>
2428
<link rel="stylesheet" href="bundle.min.css" />
2529
</head>
2630
<body>
@@ -29,18 +33,22 @@ describe('posthtml-hash', () => {
2933
</html>
3034
`
3135
)
32-
.then(result => {
36+
.then((result) => {
3337
expect(result.html).toMatchSnapshot();
3438
});
3539
});
3640

37-
it('matches the snapshot – custom hash length', () => {
41+
it("matches the snapshot – js only", () => {
3842
posthtml()
39-
.use(plugin({ path: 'src/tests/__fixtures__/processed', hashLength: 10 }))
43+
.use(plugin({ path: "src/tests/__fixtures__/processed", css: false }))
4044
.process(
4145
`
4246
<html>
4347
<head>
48+
<link
49+
rel="stylesheet"
50+
href="https://fonts.googleapis.com/css?family=Open+Sans:400,400i,600,600i,700,700i"
51+
/>
4452
<link rel="stylesheet" href="bundle.min.css" />
4553
</head>
4654
<body>
@@ -49,7 +57,77 @@ describe('posthtml-hash', () => {
4957
</html>
5058
`
5159
)
52-
.then(result => {
60+
.then((result) => {
61+
expect(result.html).toMatchSnapshot();
62+
});
63+
});
64+
65+
it("matches the snapshot – no hash", () => {
66+
posthtml()
67+
.use(
68+
plugin({
69+
path: "src/tests/__fixtures__/processed",
70+
css: false,
71+
js: false,
72+
})
73+
)
74+
.process(
75+
`
76+
<html>
77+
<head>
78+
<link
79+
rel="stylesheet"
80+
href="https://fonts.googleapis.com/css?family=Open+Sans:400,400i,600,600i,700,700i"
81+
/>
82+
<link rel="stylesheet" href="bundle.min.css" />
83+
</head>
84+
<body>
85+
<script src="bundle.min.js"></script>
86+
</body>
87+
</html>
88+
`
89+
)
90+
.then((result) => {
91+
expect(result.html).toMatchSnapshot();
92+
});
93+
});
94+
95+
it("matches the snapshot – default options", () => {
96+
posthtml()
97+
.use(plugin({ path: "src/tests/__fixtures__/processed" }))
98+
.process(
99+
`
100+
<html>
101+
<head>
102+
<link rel="stylesheet" href="bundle.min.css" />
103+
</head>
104+
<body>
105+
<script src="bundle.min.js"></script>
106+
</body>
107+
</html>
108+
`
109+
)
110+
.then((result) => {
111+
expect(result.html).toMatchSnapshot();
112+
});
113+
});
114+
115+
it("matches the snapshot – custom hash length", () => {
116+
posthtml()
117+
.use(plugin({ path: "src/tests/__fixtures__/processed", hashLength: 10 }))
118+
.process(
119+
`
120+
<html>
121+
<head>
122+
<link rel="stylesheet" href="bundle.min.css" />
123+
</head>
124+
<body>
125+
<script src="bundle.min.js"></script>
126+
</body>
127+
</html>
128+
`
129+
)
130+
.then((result) => {
53131
expect(result.html).toMatchSnapshot();
54132
});
55133
});

0 commit comments

Comments
 (0)