Skip to content

Commit 3b36871

Browse files
committed
📝 update README
1 parent 09ac7bd commit 3b36871

File tree

1 file changed

+229
-34
lines changed

1 file changed

+229
-34
lines changed

README.md

Lines changed: 229 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,39 +6,188 @@
66
[![npm](https://img.shields.io/npm/v/webpack-userscript.svg)](https://www.npmjs.com/package/webpack-userscript/v/latest)
77
[![Gitmoji](https://img.shields.io/badge/gitmoji-%20😜%20😍-FFDD67.svg?style=flat-square)](https://gitmoji.carloscuesta.me/)
88

9-
A Webpack plugin for userscript projects. 🙈
10-
11-
## Features
12-
13-
- Combine your userscript development with Webpack
14-
- Ability to generate both `.user.js` and `.meta.js`
15-
- Properly track files in watch mode
16-
- Ability to generate proxy scripts to integrate with Webpack Dev Server and TamperMonkey.
17-
> See [Issue#63](https://github.com/momocow/webpack-userscript/issues/63) for more information.
18-
- Support generating SSRIs for `@require` and `@resource` URLs.
19-
- > See [Subresource Integrity](https://www.tampermonkey.net/documentation.php#api:Subresource_Integrity) from TamperMonkey documentation.
20-
21-
## Installation
9+
A Webpack plugin for userscript projects 🙈
10+
11+
- [webpack-userscript](#webpack-userscript)
12+
- [Overview](#overview)
13+
- [Installation](#installation)
14+
- [Usage](#usage)
15+
- [Options](#options)
16+
- [Concepts](#concepts)
17+
- [What does it actually do?](#what-does-it-actually-do)
18+
- [Prepend headers to userscripts](#prepend-headers-to-userscripts)
19+
- [Generate metadata files](#generate-metadata-files)
20+
- [Generate proxyscript files](#generate-proxyscript-files)
21+
- [Headers pipeline](#headers-pipeline)
22+
- [Load headers](#load-headers)
23+
- [Rename ambiguous tags](#rename-ambiguous-tags)
24+
- [Resolve base URLs](#resolve-base-urls)
25+
- [Process SSRIs](#process-ssris)
26+
- [Provide default values for tags](#provide-default-values-for-tags)
27+
- [Generate proxyscripts](#generate-proxyscripts)
28+
- [Interpolate templates inside values](#interpolate-templates-inside-values)
29+
- [Validate headers](#validate-headers)
30+
- [Render headers](#render-headers)
31+
- [Guides](#guides)
32+
- [Hot Development](#hot-development)
33+
- [Integration with Webpack Dev Server and TamperMonkey](#integration-with-webpack-dev-server-and-tampermonkey)
34+
- [I18n headers](#i18n-headers)
35+
- [Furthermore](#furthermore)
36+
37+
## Overview
38+
39+
### Installation
2240

2341
```bash
2442
npm i webpack-userscript -D
2543
```
2644

27-
## Usage
28-
29-
### webpack.config.js
45+
### Usage
3046

31-
Include the plugin in the `webpack.config.js` as the following example.
47+
Import and configure the plugin in the `webpack.config.js` as the following example.
3248

3349
```js
3450
const { UserscriptPlugin } = require('webpack-userscript');
3551

3652
module.exports = {
37-
plugins: [new UserscriptPlugin()],
53+
plugins: [new UserscriptPlugin(/* optionally provide more options here */)],
3854
};
3955
```
4056

41-
## Features
57+
### Options
58+
59+
See [UserscriptOptions](https://cow.moe/webpack-userscript/types/UserscriptOptions.html) for all configurations.
60+
61+
## Concepts
62+
63+
### What does it actually do?
64+
65+
#### Prepend headers to userscripts
66+
67+
The main purpose of this plugin is to generate userscript headers, and prepend them as a comment block into output entry scripts whose names are conventionally ending with `.user.js`.
68+
69+
There are several userscript engines on the internet and some of them call userscript headers in different names; but don't worry because they share the same concept and **almost** the same format.
70+
71+
Here are some references to headers definitions of userscript engines:
72+
73+
- [TamperMonkey: userscript headers](https://www.tampermonkey.net/documentation.php#meta)
74+
- [GreaseMonkey: metadata block](https://wiki.greasespot.net/Metadata_Block)
75+
- [GreasyFork: meta keys](https://greasyfork.org/en/help/meta-keys)
76+
- [ViolentMonkey: metadata block](https://violentmonkey.github.io/api/metadata-block/)
77+
78+
#### Generate metadata files
79+
80+
Besides prepending headers to entry scripts, it can optionally generate metadata files which are userscript files without codes; that is, they contain headers only. Metadata files are used to save bandwidth when checking updates. By convention, their names are ending with `.meta.js`.
81+
82+
#### Generate proxyscript files
83+
84+
The concept of proxyscript is introduced by this plugin, unlike userscripts and metadata files which are commonly known. The name of a proxyscript should end with `.proxy.user.js`. It is mainly designed to work around the caching behavior of userscript engines like TamperMonkey. It was a pain point for userscript developers who set up a development environment with Webpack Dev Server and require fresh reloads to test their scripts.
85+
86+
> See more details in [issue #63](https://github.com/momocow/webpack-userscript/issues/63)
87+
88+
It is worth mentioning that with ViolentMonkey you might experience a better reload story, according to [a feedback in issue #63](https://github.com/momocow/webpack-userscript/issues/63#issuecomment-1500167848).
89+
90+
### Headers pipeline
91+
92+
#### Load headers
93+
94+
Headers can be provided directly as an object, a string referencing to a file, or a function returning an object of headers.
95+
96+
The plugin will also try to load initial headers from the following fields, `name`, `description`, `version`, `author`, `homepage` and `bugs` in `package.json`.
97+
98+
Headers files are added as a file dependency; therefore, changes to headers files are watched by Webpack during developing in the watch mode.
99+
100+
#### Rename ambiguous tags
101+
102+
The main purpose is to fix misspelling or wrong letter case.
103+
104+
- `updateUrl` => `updateURL`
105+
- `iconUrl` => `iconURL`
106+
- `icon64Url` => `icon64URL`
107+
- `installUrl` => `installURL`
108+
- `supportUrl` => `supportURL`
109+
- `downloadUrl` => `downloadURL`
110+
- `homepageUrl` => `homepageURL`
111+
112+
#### Resolve base URLs
113+
114+
Base URLs are resolved for `downloadURL` and `updateURL`.
115+
116+
If `updateBaseURL` is not provided, `downloadBaseURL` will be used; if metajs is disabled, `updateURL` will point to the file of userjs.
117+
118+
#### Process SSRIs
119+
120+
[Subresource Integrity](https://www.tampermonkey.net/documentation.php#api:Subresource_Integrity) is used to ensure the 3rd-party assets do not get mocked by the man in the middle.
121+
122+
URLs in `@require` and `@resource` tags can have their SSRIs be generated and locked in a SSRI lock file whose name is default to `ssri-lock.json`.
123+
124+
Missing SSRIs will be computed right in the compilation, which indicates that developers have to ensure their 3rd-party assets to be trustable during compilation.
125+
126+
If one cannot ensure 3rd-party assets to be trustable, he can modify the lock file himself with trustable integrities of assets.
127+
128+
> Note that the lock file should be commited into the version control system just like `package-lock.json`.
129+
130+
#### Provide default values for tags
131+
132+
If there is no any `@include` or `@match` tag provided, a wildcard `@match`, `*://*/*`, is used.
133+
134+
#### Generate proxyscripts
135+
136+
The content of a proxyscript looks similar to a metajs except that its `@require` tag will include an URL linked to its userjs file and it won't have any one of these tags, `downloadURL`, `updateURL` and `installURL`.
137+
138+
#### Interpolate templates inside values
139+
140+
Leaf values of headers can be interpolable templates. Template variables can be represented in a format, `[var]`, just like how [template strings in Webpack output options](https://webpack.js.org/configuration/output/#template-strings) look like.
141+
142+
Possible template variables are as follows.
143+
144+
- `[name]`: chunk name
145+
- `[buildNo]`: build number starting from 1 at beginning of watch mode
146+
- `[buildTime]`: the timestamp in millisecond when the compilation starts
147+
- `[file]`: full path of the file
148+
- = `[dirname]` + `[basename]` + `[extname]` + `[query]`
149+
- `[filename]`: file path
150+
- = `[basename]` + `[extname]`
151+
- `[dirname]`: directory path
152+
- `[basename]`: file base name
153+
- `[extname]`: file extension starting with `.`
154+
- `[query]`: query string starting with `?`
155+
156+
> Note that `[buildNo]` starts from 0 and will increase during developing in the watch mode.
157+
> Once exiting from the watch mode, it will be reset.
158+
159+
For example, one can embed the build time into `@version` tag via the following configuration.
160+
161+
```js
162+
new UserscriptPlugin({
163+
headers: {
164+
version: '0.0.1-beta.[buildTime]'
165+
},
166+
})
167+
```
168+
169+
#### Validate headers
170+
171+
Headers will be transformed and validated with the help of [`class-transformer`](https://github.com/typestack/class-transformer) and [`class-validator`](https://github.com/typestack/class-validator).
172+
173+
The configuration defaults to strict mode, which means extra tags are not allowed and type checking to headers values are performed.
174+
175+
One can provide `headersClass` option to override the default `Headers` class; but it is suggested to inherit from the original one.
176+
177+
> Note that the `headersClass` is used for both main headers and i18n headers.
178+
> Check the [default implementation](lib/features/validate-headers/headers.ts) before customizing your own.
179+
180+
#### Render headers
181+
182+
Headers in all locales are merged and rendered.
183+
184+
There are 2 useful options here, `pretty` and `tagOrder`.
185+
186+
The `pretty` option is a boolean deciding whether to render the headers as a table or not.
187+
188+
The `tagOrder` option is a precedence list of tag names which should be followed. Listed tags are rendered first; unlisted tags are rendered after listed ones, in ASCII order.
189+
190+
## Guides
42191

43192
### Hot Development
44193

@@ -118,22 +267,68 @@ new WebpackUserscript({
118267
});
119268
```
120269

121-
### Interpolation
122270

123-
Possible interpolation variables are as follows.
124271

125-
- `[name]`: chunk name
126-
- `[buildNo]`: build number starting from 1 at beginning of watch mode
127-
- `[buildTime]`: the timestamp in millisecond when the compilation starts
128-
- `[file]`: full path of the file
129-
- = `[dirname]` + `[basename]` + `[extname]` + `[query]`
130-
- `[filename]`: file path
131-
- = `[basename]` + `[extname]`
132-
- `[dirname]`: directory path
133-
- `[basename]`: file base name
134-
- `[extname]`: file extension starting with `.`
135-
- `[query]`: query string starting with `?`
136272

137-
## Configuration
273+
### I18n headers
274+
275+
I18n headers can be provided as an object, a string (a.k.a headers file) or a function (a.k.a headers provider), just like the main headers.
276+
277+
```js
278+
new UserscriptPlugin({
279+
headers: {
280+
name: 'this is the main script name'
281+
},
282+
i18n: {
283+
// headers object
284+
'en-US': {
285+
name: 'this is a localized name'
286+
},
287+
},
288+
})
289+
```
290+
291+
292+
```js
293+
new UserscriptPlugin({
294+
headers: {
295+
name: 'this is the main script name'
296+
},
297+
i18n: {
298+
// headers file
299+
'en-US': '/dir/to/headers.json' // whose content is `{"name": "this is a localized name"}`
300+
},
301+
})
302+
```
303+
304+
```js
305+
new UserscriptPlugin({
306+
headers: {
307+
name: 'this is the main script name'
308+
},
309+
i18n: {
310+
// headers provider
311+
'en-US': (headers) => ({
312+
...headers,
313+
name: 'this is a localized name'
314+
}),
315+
},
316+
})
317+
```
318+
319+
320+
With the above configurations will generate the following headers,
321+
322+
```js
323+
// ==UserScript==
324+
// @name this is the main script name
325+
// @name:en-US this is a localized name
326+
// @version 0.0.0
327+
// @match *://*/*
328+
// ==/UserScript==
329+
```
138330

139-
See [UserscriptOptions](https://cow.moe/webpack-userscript/types/UserscriptOptions.html).
331+
## Furthermore
332+
- [Get started with Webpack](https://webpack.js.org/guides/getting-started/)
333+
- [How to write userscript in TypeScript?](https://github.com/momocow/webpack-userscript/issues/95)
334+
- [Solution to userscript not refreshing on every page load](https://github.com/momocow/webpack-userscript/issues/63)

0 commit comments

Comments
 (0)