Skip to content
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

Add support for browser bundle #4796

Closed
wants to merge 68 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
a4a7149
Move lintPostcssResult to a separate module
m-allanson May 3, 2020
3b9c8bf
Add entrypoint for standalone bundle
m-allanson May 3, 2020
4643539
Add bundle script
m-allanson May 3, 2020
a70460e
Try bundling syntaxes
m-allanson May 4, 2020
f0c81e2
Enable alternate syntax parsers
m-allanson May 4, 2020
4eb613d
Add temporary html demo
m-allanson May 4, 2020
1f92941
Fix error when re-selecting 'css' syntax
m-allanson May 4, 2020
ddb0efd
Add a command for bundle stats
m-allanson May 5, 2020
7315c27
Move browser entrypoint
m-allanson May 6, 2020
1a20046
Expose normalizeAllRuleSettings and use in place of inline shim
m-allanson May 6, 2020
cda1c6b
Start to replicate standalone API
m-allanson May 6, 2020
0c3eb8e
Update bundle scripts
m-allanson May 6, 2020
037b039
Update demo to match new function signature
m-allanson May 6, 2020
761e7fa
Use new createPartialStylelintResult in browser entry point
m-allanson May 6, 2020
bb3acc6
Remove unnecessary variable
m-allanson May 6, 2020
69a5d6e
Pass in options only for better types
m-allanson May 6, 2020
4ddad17
Fix up some types
m-allanson May 7, 2020
349644c
WIP: extract prepareReturnValue out to a separate module
m-allanson May 7, 2020
35ca844
Create type aliases for formatters
m-allanson May 7, 2020
59951c0
Update formatter developer docs
m-allanson May 7, 2020
558b8dd
Apply new formatter types to result creation
m-allanson May 7, 2020
38e9e82
Fix check for valid formatter
m-allanson May 7, 2020
a891ae8
Re-enable debug calls
m-allanson May 7, 2020
49e3c94
Return a result instead of throwing on CssSyntaxError
m-allanson May 10, 2020
d0082b1
Update ignores and use more consistent type imports
m-allanson May 8, 2020
5ede16c
Re-enable passing second arg `returnValue` to formatter functions
m-allanson May 10, 2020
9abb987
Enable stylelint's fix option
m-allanson May 10, 2020
a335bba
First draft of docs for browser API
m-allanson May 11, 2020
6785443
WIP: Load syntaxes at runtime without changing existing customSyntax API
m-allanson May 11, 2020
d5ffe67
Add temporary html file
m-allanson May 11, 2020
7e51049
Overload the customSyntax option to accept a syntax object
m-allanson May 12, 2020
5ffc2b8
Use named export instead of default
m-allanson May 13, 2020
78806e0
Run system tests on the browser entrypoint
m-allanson May 13, 2020
f6f7119
Use equal length variable names to highlight config diffs more clearly
m-allanson May 13, 2020
3ce8581
Tidy up descriptions and remove unnecessary snapshot
m-allanson May 13, 2020
a360430
Add some tests and stronger input validation
m-allanson May 14, 2020
312952c
Overload customSyntax option to additionally accept a syntax object
m-allanson May 14, 2020
e015fb8
Hackety hack
m-allanson May 15, 2020
0960ea4
Add failing test that checks all syntaxes are objects
m-allanson May 19, 2020
3b63096
Fix failing syntax test
m-allanson May 19, 2020
c50bb02
Add TODO
m-allanson May 20, 2020
a21904c
Tidy up dist dir
m-allanson May 21, 2020
1b3ec1e
Do another pass on the docs
m-allanson May 21, 2020
3a6dab9
Remove unused deps
m-allanson May 21, 2020
0f51d72
Minify bundles
m-allanson May 21, 2020
58a8034
Fix lint error
m-allanson May 21, 2020
d0194e5
Move getFormatterFunction back into standalone
m-allanson May 25, 2020
92904dc
Update package-lock.json
m-allanson Jun 3, 2020
ae22a5c
Merge branch 'master' into browser-bundle
m-allanson Jun 10, 2020
c8dd0a9
Update parcel 2 from alpha to beta version
m-allanson Jun 18, 2020
30cc66f
Merge branch 'master' into browser-bundle
m-allanson Jun 20, 2020
f375429
Delete temp test files
m-allanson Jun 20, 2020
48ccd71
Merge branch 'master' into browser-bundle
m-allanson Jun 22, 2020
2051637
Reverse unnecessary whitespace change
m-allanson Jun 23, 2020
8a74537
Use Parcel API instead of the CLI
m-allanson Jul 1, 2020
2ad2b5e
Add some comments and log out build stats for each bundle
m-allanson Jul 1, 2020
642bd32
A bit more tidying
m-allanson Jul 2, 2020
6d9ff23
Merge branch 'master' into browser-bundle
m-allanson Jul 8, 2020
32a9a8b
eslint was not happy
m-allanson Jul 15, 2020
56ff536
Merge branch 'master' into browser-bundle
m-allanson Jul 23, 2020
5599148
Merge branch 'master' into browser-bundle
m-allanson Sep 3, 2020
1d7a889
Clearer naming
m-allanson Nov 5, 2020
d9f9b80
Merge branch 'master' into browser-bundle
m-allanson Nov 5, 2020
b13be22
Updated deps
m-allanson Nov 5, 2020
0b549ae
This was meant to be removed in 1d7a88
m-allanson Nov 5, 2020
4aa06c4
Fix unexpected lint error?
m-allanson Nov 5, 2020
b5900e9
Update filenames for tests
m-allanson Nov 5, 2020
fdb24ea
Remove demo from dist directory
m-allanson Nov 5, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
@@ -1,6 +1,7 @@
.coverage
lib/vendor
lib/utils/parseCalcExpression/parser.js
dist

# Unignore config files like .prettierrc.js, because they're ignored by default
!.*rc.js
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -2,4 +2,6 @@ node_modules
*.log
.coverage
.eslintcache
.vscode
yarn.lock
.parcel-cache
1 change: 1 addition & 0 deletions .prettierignore
Expand Up @@ -10,6 +10,7 @@
**/fixtures/**/*.vue
**/fixtures/**/*.html
**/fixtures/**/*.markdown
dist/*.js
lib/utils/parseCalcExpression/parser.js
scripts/**/*.css
system-tests/**/*.css
Expand Down
4 changes: 4 additions & 0 deletions dist/.gitignore
@@ -0,0 +1,4 @@
*
!.gitignore
!index.html
!esm-test.html
246 changes: 246 additions & 0 deletions docs/user-guide/usage/browser.md
@@ -0,0 +1,246 @@
# Web Browser (experimental)

You can use stylelint in the browser using the experimental ES module (ESM) bundle.

The ESM bundle supports a subset of the [Node API](./node-api.md)'s functionality. The `code` and `config` options are required values.

Notably the ESM bundle has _no_ support for config files, ignore files, CLI usage, plugins or custom rules. Custom syntaxes are supported by manually passing them in to stylelint.

An example:

```html
<html>
<head>
<script type="module">
import sl from "./stylelint-esm.js";

async function run() {
const options = {
code: `a { color: #fff; }`,
config: {
rules: {
"color-hex-length": "long"
}
}
};

const result = await sl.lint(options);
console.log(result);
}

run();
</script>
</head>
<body></body>
</html>
```

### Formatters

JSON formatter only. No other formatters supported (for now)

TODO: expand this section

### Syntaxes

Stylelint's default CSS syntax is available by default.

Syntax bundles can be large. Therefore custom syntaxes (SCSS, Less, CSS-in-JSS, etc) must be loaded manually. Bundles are provided for all officially supported syntaxes. [View the examples for more details]() (TODO fix link).

TODO: expand this section

## Options

Stylelint's browser bundle supports a subset of the Node API's options. The following options are supported:

- [code]() (required, must be a string)
- [config](../configure.md) (required, must be an object)
- [customSyntax](../configure.md) (optional, if used it must be an object)
- [fix]()
- [maxWarnings]()
- [ignoreDisables]()
- [reportNeedlessDisables]()
- [reportInvalidScopeDisables]()

## The returned promise

The return value has the same format as [the Node API's return value]().

## Usage examples

### Example A - default syntax

Linting a plain CSS string.

```html
<html>
<head>
<script type="module">
import sl from "./stylelint-esm.js";

async function run() {
const options = {
code: `a { color: #fff; }`,
config: {
rules: {
"color-hex-length": "long"
}
}
};

const result = await sl.lint(options);
console.log(result);
}

run();
</script>
</head>
<body></body>
</html>
```

### Example B - SCSS syntax

Linting an SCSS string, using the `syntax-scss` custom parser.

```html
<html>
<head>
<title>demo demo demo</title>
<script type="module">
import sl from "./stylelint-esm.js";
import syntaxScss from "./syntax-scss.js";

async function run() {
const options = {
code: `a.#{var} { color: #fff; }`,
config: {
rules: {
"color-hex-length": "long"
}
},
customSyntax: syntaxScss
};

const result = await sl.lint(options);
console.log(result);
}

run();
</script>
</head>
<body></body>
</html>
```

### Example C - loading syntaxes on-demand

Load any custom syntax on demand. You can [view this example online](http://stylelint-browser-bundle.netlify.app/).

```html
<html>
<head> </head>
<body>
<h1>stylelint</h1>
<p>Edit code or config to see updated results</p>
<label for="syntax">Select syntax:</label>
<select name="syntax" id="syntax">
<option value="css">css</option>
<option value="./syntax-css-in-js.js">css-in-js</option>
<option value="./syntax-html.js">html</option>
<option value="./syntax-less.js">less</option>
<option value="./syntax-markdown.js">markdown</option>
<option value="./syntax-sass.js">sass</option>
<option value="./syntax-scss.js">scss</option>
<option value="./syntax-sugarss.js">sugarss</option>
</select>
<h2>code</h2>
<textarea id="code" style="width: 100%; height: 200px;">
a {color: #FFF; }
</textarea
>
<h2>config</h2>
<textarea id="config" style="width: 100%; height: 200px;">
{
"rules": {
"color-hex-length": "long",
"at-rule-no-vendor-prefix": true
}
}
</textarea
>
<h2>results</h2>
<code id="results" style="white-space: pre;"></code>
<script type="module">
import sl from "./stylelint-esm.js";

async function main() {
const syntaxEl = document.querySelector("#syntax");
const codeEl = document.querySelector("#code");
const configEl = document.querySelector("#config");
const resultsEl = document.querySelector("#results");
let syntaxCache = {};
let selectedSyntax;

syntaxEl.addEventListener("change", setSyntax);
codeEl.addEventListener("keyup", lint);
configEl.addEventListener("keyup", lint);

/* Load cached or remote syntax parser */
async function setSyntax(event) {
selectedSyntax =
event.target.value === "css" ? null : event.target.value;
if (selectedSyntax === null) {
lint();
return;
}

if (syntaxCache[selectedSyntax]) {
lint();
} else {
resultsEl.textContent = `Loading syntax: ${selectedSyntax}`;
const syntax = await import(selectedSyntax);
syntaxCache[selectedSyntax] = syntax.default;
lint();
}
}

async function lint() {
let results;
try {
const options = {
code: codeEl.value,
config: JSON.parse(`[${configEl.value}]`)[0]
};

if (selectedSyntax && syntaxCache[selectedSyntax]) {
options.customSyntax = syntaxCache[selectedSyntax];
}
results = await sl.lint(options);
} catch (error) {
resultsEl.textContent = error;
}

try {
resultsEl.textContent = JSON.stringify(results, null, 4);
} catch (error) {
console.log("Stringify error", error); // sometimes results is too large to stringify, throwing a RangeError
console.log(
"showing results.output instead of full results object"
);
resultsEl.textContent = JSON.stringify(
JSON.parse(results.output),
null,
4
);
}
}

lint();
}

main();
</script>
</body>
</html>
```