Skip to content

Commit

Permalink
feat: support <link> elements in svelte (#426)
Browse files Browse the repository at this point in the history
* feat: add basic <link> support

* docs: add <link> references

* chore: snapshot update
  • Loading branch information
tivac authored Jun 3, 2018
1 parent 1401885 commit 49f8f0a
Show file tree
Hide file tree
Showing 12 changed files with 812 additions and 1,070 deletions.
78 changes: 78 additions & 0 deletions docs/svelte.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Svelte

`modular-css-svelte` provides a [svelte preprocessor](https://svelte.technology/guide#preprocessing) that can convert inline `<style>` or external `<link>` tags using `modular-css` and will also staticly replace any css references it can find for maximum speed.

### Options

All options are passed to the underlying `Processor` instance, see [Options](api.md#options).

## Usage

### `svelte.preprocess()`

```js
const filename = "./Component.html";

const { processor, preprocess } = require("modular-css-svelte")({
css : "./dist/bundle.css"
});

const processed = await svelte.preprocess(
fs.readFileSync(filename, "utf8"),
Object.assign({}, preprocess, { filename })
);

const result = processor.output();

fs.writeFileSync("./dist/bundle.css", result.css);
```

### `rollup-plugin-svelte`

#### API

```js
const rollup = require("rollup").rollup;

const { preprocess, plugin } = require("modular-css-svelte/rollup")({
css : "./dist/bundle.css"
});

const bundle = await rollup({
input : "./Component.html",
plugins : [
require("rollup-plugin-svelte")({
preprocess
}),
plugin
]
});

// bundle.write will also write out the CSS to the path specified in the `css` arg
bundle.write({
format : "es",
file : "./dist/bundle.js"
});
```

#### `rollup.config.js`

```js
const { preprocess, plugin } = require("modular-css-svelte/rollup")({
css : "./dist/bundle.css"
});

module.exports = {
input : "./Component.html",
output : {
format : "es",
file : "./dist/bundle.js"
},
plugins : [
require("rollup-plugin-svelte")({
preprocess
}),
plugin
]
};
```
9 changes: 5 additions & 4 deletions packages/svelte/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ modular-css-svelte [![NPM Version](https://img.shields.io/npm/v/modular-css-sve
<a href="https://gitter.im/modular-css/modular-css"><img src="https://img.shields.io/gitter/room/modular-css/modular-css.svg" alt="Gitter" /></a>
</p>

Svelte preprocessor support for [`modular-css`](https://github.com/tivac/modular-css). Process inline `<style>`s inside your Svelte components using the full power of `modular-css` while also providing compile-time optimizations for smaller bundles and even faster runtime performance!
Svelte preprocessor support for [`modular-css`](https://github.com/tivac/modular-css). Process inline `<style>`s or `<link>` references inside your Svelte components using the full power of `modular-css` while also providing compile-time optimizations for smaller bundles and even faster runtime performance!

## Example

Turns this

```html
<div class="{{css.main}}">
<h1 class="{{css.title}}">Title</h1>
<div class="{css.main}">
<h1 class="{css.title}">Title</h1>
</div>

<style>
Expand All @@ -37,6 +37,8 @@ into what is effectively this

while allowing you to use all of the usual `modular-css` goodies.

Alternatively you can use `<link>` tags to reference CSS external to the component.

## Install

`$ npm i modular-css-svelte`
Expand Down Expand Up @@ -115,4 +117,3 @@ module.exports = {
## Options

All options are passed to the underlying `Processor` instance, see [Options](https://github.com/tivac/modular-css/blob/master/docs/api.md#options).

81 changes: 52 additions & 29 deletions packages/svelte/methods.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,62 @@
"use strict";

const path = require("path");

const resolve = require("resolve-from");

const styleRegex = /<style[\S\s]*?>([\S\s]*?)<\/style>/igm;
const linkRegex = /<link\b[^<>]*?\bhref=\s*(?:"([^"]+)"|'([^']+)'|([^>\s]+))[^>]*>/igm;

exports.markup = (processor) => ({ content, filename }) => {
const search = /<style[\S\s]*?>([\S\s]*?)<\/style>/igm;
const matches = search.exec(content);
const link = linkRegex.exec(content);
const style = styleRegex.exec(content);

if(!matches) {
return {
code : content
};
}
if(!link && !style) {
return {
code : content
};
}

const style = matches[1];
if(link && style) {
throw new Error("modular-css-svelte supports <style> OR <link>, but not both");
}

return processor.string(
let css;

if(style) {
css = processor.string(
filename,
style
)
.then((result) => {
const exported = result.files[result.file].exports;

return {
code : content
// Replace simple {css.<key>} values first
.replace(
new RegExp(`{css.(${Object.keys(exported).join("|")})}`, "gm"),
(match, key) => exported[key].join(" ")
)
// Then any remaining bare css.<key> values
.replace(
new RegExp(`(\\b)css.(${Object.keys(exported).join("|")})(\\b)`, "gm"),
(match, prefix, key, suffix) => `${prefix}"${exported[key].join(" ")}"${suffix}`
)
};
});
};
style[1]
);
}

if(link) {
// Remove the <link> element from the component to avoid double-loading
content = content.replace(link[0], "");

let external = resolve(path.dirname(filename), link[1] || link[2] || link[3]);

css = processor.file(external);
}

return css.then((result) => {
const exported = result.files[result.file].exports;

return {
code : content
// Replace simple {css.<key>} values first
.replace(
new RegExp(`{css.(${Object.keys(exported).join("|")})}`, "gm"),
(match, key) => exported[key].join(" ")
)
// Then any remaining bare css.<key> values
.replace(
new RegExp(`(\\b)css.(${Object.keys(exported).join("|")})(\\b)`, "gm"),
(match, prefix, key, suffix) => `${prefix}"${exported[key].join(" ")}"${suffix}`
)
};
});
};

exports.style = () => ({
code : "/* replaced by modular-css */"
Expand Down
Loading

0 comments on commit 49f8f0a

Please sign in to comment.