svelte-preprocess
Advanced tools
Comparing version 2.5.2 to 2.6.0
@@ -7,2 +7,9 @@ ### Changelog | ||
#### [2.5.2](https://github.com/kaisermann/svelte-preprocess/compare/v2.5.1...2.5.2) | ||
> 10 April 2019 | ||
- feat: 🎸 support async onBefore() [`53ec690`](https://github.com/kaisermann/svelte-preprocess/commit/53ec690d4bf28c10b3caa4051fe8d072cca2804a) | ||
- chore: 🤖 update changelog [`557f91a`](https://github.com/kaisermann/svelte-preprocess/commit/557f91ae2b852c5c800746803f46bead8f43d010) | ||
#### [v2.5.1](https://github.com/kaisermann/svelte-preprocess/compare/v2.4.2...v2.5.1) | ||
@@ -9,0 +16,0 @@ |
{ | ||
"name": "svelte-preprocess", | ||
"version": "2.5.2", | ||
"version": "2.6.0", | ||
"license": "MIT", | ||
@@ -47,6 +47,6 @@ "main": "src/index.js", | ||
"stylus": "^0.54.5", | ||
"svelte": "^2.16.1" | ||
"svelte": "^3.0.0-beta.16" | ||
}, | ||
"peerDependencies": { | ||
"svelte": "^1.44.0 || ^2.0.0" | ||
"svelte": "^1.44.0 || ^2.0.0 || ^3.0.0" | ||
}, | ||
@@ -53,0 +53,0 @@ "dependencies": { |
@@ -20,4 +20,6 @@ # Svelte Preprocess | ||
### Basic | ||
### Auto Preprocessing | ||
#### Basic | ||
```js | ||
@@ -30,3 +32,3 @@ const svelte = require('svelte') | ||
### Advanced | ||
#### Advanced | ||
@@ -95,3 +97,3 @@ ```js | ||
* Using the same matching algorithm as above, don't parse, | ||
* modify, or remove from the markup, tags which match the | ||
* modify, or remove from the markup, tags which match the | ||
* language / types listed below. | ||
@@ -106,2 +108,29 @@ * **/ | ||
### Standalone processors | ||
Instead of a single processor, [Svelte v3 has added support for multiple processors](https://v3.svelte.technology/docs#svelte-preprocess). In case you want to manually configure your preprocessing step, `svelte-preprocess` exports these named processors: `pug`, `coffeescript` or `coffee`, `less`, `scss` or `sass`, `stylus`, `postcss`. | ||
```js | ||
svelte.preprocess(input, [ | ||
pug(), | ||
coffee(), | ||
scss(), | ||
]).then(...) | ||
``` | ||
Every processor accepts an option object which is passed to its respective underlying tool. | ||
```js | ||
svelte.preprocess(input, [ | ||
scss(), | ||
postcss({ | ||
plugins: [ | ||
require('autoprefixer')({ browsers: 'last 2 versions' }) | ||
] | ||
}), | ||
]) | ||
``` | ||
***Note:** there's no built-in support for \<template\> tag or external files when using standalone processors.* | ||
### With `svelte-loader` | ||
@@ -132,4 +161,6 @@ | ||
### Template (a la Vue) tag support | ||
### Template tag support | ||
*Note: only for auto preprocessing* | ||
```html | ||
@@ -147,2 +178,4 @@ <template> | ||
*Note: only for auto preprocessing* | ||
```html | ||
@@ -156,6 +189,5 @@ <template src="template.html"></template> | ||
Current supported out-of-the-box preprocessors are `SCSS`, `Stylus`, `Less`, `Coffeescript`, `Pug`. | ||
Current supported out-of-the-box preprocessors are `SCSS`, `Stylus`, `Less`, `Coffeescript`, `Pug` and `PostCSS`. | ||
```html | ||
<template lang="pug"> | ||
@@ -193,4 +225,4 @@ div Hey | ||
div | ||
color: $color | ||
color: $color; | ||
</style> | ||
``` |
183
src/index.js
@@ -1,168 +0,27 @@ | ||
const stripIndent = require('strip-indent') | ||
const autoProcess = require('./autoProcess.js') | ||
const { | ||
addLanguageAlias, | ||
getLanguage, | ||
runTransformer, | ||
isFn, | ||
parseAttributes, | ||
getSrcContent, | ||
resolveSrc, | ||
throwUnsupportedError, | ||
getTagPattern, | ||
sliceReplace, | ||
aliasOverrides, | ||
} = require('./utils.js') | ||
const coffeescript = require('./processors/coffeescript.js') | ||
const less = require('./processors/less.js') | ||
const postcss = require('./processors/postcss.js') | ||
const pug = require('./processors/pug.js') | ||
const scss = require('./processors/scss.js') | ||
const stylus = require('./processors/stylus.js') | ||
const TEMPLATE_PATTERN = getTagPattern('template') | ||
/** default auto processor */ | ||
module.exports = autoProcess | ||
module.exports = ({ | ||
onBefore, | ||
transformers = {}, | ||
aliases, | ||
preserve = [], | ||
} = {}) => { | ||
const optionsCache = {} | ||
/** stand-alone processors to be included manually */ | ||
if (aliases && aliases.length) { | ||
addLanguageAlias(aliases) | ||
} | ||
/** Markup */ | ||
exports.pug = pug | ||
const getTransformerOpts = (lang, alias) => { | ||
if (isFn(transformers[alias])) return transformers[alias] | ||
if (isFn(transformers[lang])) return transformers[lang] | ||
/** Script */ | ||
exports.coffeescript = coffeescript | ||
exports.coffee = coffeescript | ||
if (typeof optionsCache[alias] === 'undefined') { | ||
let opts = transformers[lang] || {} | ||
if (lang !== alias) { | ||
opts = { | ||
...opts, | ||
...(aliasOverrides[alias] || {}), | ||
...(transformers[alias] || {}), | ||
} | ||
} | ||
optionsCache[alias] = opts | ||
} | ||
return optionsCache[alias] | ||
} | ||
const getTransformerTo = targetLanguage => async ({ | ||
content = '', | ||
attributes, | ||
filename, | ||
}) => { | ||
const { lang, alias } = getLanguage(attributes, targetLanguage) | ||
const dependencies = [] | ||
if (preserve.includes(lang) || preserve.includes(alias)) { | ||
return | ||
} | ||
if (attributes.src) { | ||
if (attributes.src.match(/^(https?)?:?\/\/.*$/)) { | ||
return | ||
} | ||
const file = resolveSrc(filename, attributes.src) | ||
content = await getSrcContent(file) | ||
dependencies.push(file) | ||
} | ||
if (lang === targetLanguage) { | ||
return { | ||
code: content, | ||
dependencies, | ||
} | ||
} | ||
if ( | ||
transformers[lang] === false || | ||
(lang !== alias && transformers[alias] === false) | ||
) { | ||
throwUnsupportedError(alias, filename) | ||
} | ||
const result = await runTransformer(lang, getTransformerOpts(lang, alias), { | ||
content: stripIndent(content), | ||
filename, | ||
}) | ||
result.dependencies = dependencies | ||
return result | ||
} | ||
const markupTransformer = async ({ content, filename }) => { | ||
if (isFn(onBefore)) { | ||
content = await onBefore({ content, filename }) | ||
} | ||
const templateMatch = content.match(TEMPLATE_PATTERN) | ||
/** If no <template> was found, just return the original markup */ | ||
if (!templateMatch) { | ||
return { code: content } | ||
} | ||
let [, attributes, templateCode] = templateMatch | ||
attributes = parseAttributes(attributes) | ||
const { lang, alias } = getLanguage(attributes, 'html') | ||
const dependencies = [] | ||
if (attributes.src) { | ||
const file = resolveSrc(filename, attributes.src) | ||
templateCode = await getSrcContent(file) | ||
dependencies.push(file) | ||
} | ||
/** If language is HTML, just remove the <template></template> tags */ | ||
if (lang === 'html') { | ||
return { | ||
code: sliceReplace(templateMatch, content, templateCode), | ||
dependencies, | ||
} | ||
} | ||
if (transformers[lang] === false) { | ||
throwUnsupportedError(lang, filename) | ||
} | ||
const { code } = await runTransformer( | ||
lang, | ||
getTransformerOpts(lang, alias), | ||
{ | ||
content: stripIndent(templateCode), | ||
filename, | ||
}, | ||
) | ||
return { | ||
code: sliceReplace(templateMatch, content, code), | ||
dependencies, | ||
} | ||
} | ||
const scriptTransformer = getTransformerTo('javascript') | ||
const cssTransformer = getTransformerTo('css') | ||
const styleTransformer = assetInfo => { | ||
const transformedCSS = cssTransformer(assetInfo) | ||
if (transformers.postcss) { | ||
return Promise.resolve(transformedCSS).then(({ code, map }) => { | ||
return runTransformer('postcss', transformers.postcss, { | ||
content: stripIndent(code), | ||
filename: assetInfo.filename, | ||
map, | ||
}) | ||
}) | ||
} | ||
return transformedCSS | ||
} | ||
return { | ||
markup: markupTransformer, | ||
script: scriptTransformer, | ||
style: styleTransformer, | ||
} | ||
} | ||
/** Style */ | ||
exports.less = less | ||
exports.scss = scss | ||
exports.sass = scss | ||
exports.stylus = stylus | ||
exports.postcss = postcss |
const coffeescript = require('coffeescript') | ||
module.exports = function({ content, filename, options }) { | ||
module.exports = ({ content, filename, options }) => { | ||
const { js: code, sourceMap: map } = coffeescript.compile(content, { | ||
@@ -5,0 +5,0 @@ filename, |
const less = require('less/lib/less-node') | ||
module.exports = function({ content, filename, options }) { | ||
module.exports = ({ content, filename, options }) => { | ||
return less | ||
@@ -5,0 +5,0 @@ .render(content, { |
const postcss = require('postcss') | ||
const postcssLoadConfig = require(`postcss-load-config`) | ||
const process = (plugins, content, filename, map) => | ||
postcss(plugins) | ||
.process(content, { | ||
from: filename, | ||
prev: map, | ||
}) | ||
.then(({ css, map }) => ({ | ||
code: css, | ||
map, | ||
})) | ||
const process = async (plugins, content, filename, sourceMap) => { | ||
const { css, map } = await postcss(plugins).process(content, { | ||
from: filename, | ||
prev: sourceMap, | ||
}) | ||
return { code: css, map } | ||
} | ||
/** Adapted from https://github.com/TehShrike/svelte-preprocess-postcss */ | ||
module.exports = ({ content, filename, options, map = undefined }) => { | ||
module.exports = async ({ content, filename, options, map = undefined }) => { | ||
/** If manually passed a plugins array, use it as the postcss config */ | ||
return typeof options.plugins !== 'undefined' | ||
? process(options.plugins, content, filename, map) | ||
: /** If not, look for a postcss config file */ | ||
postcssLoadConfig(options, options.configFilePath) | ||
.then(options => process(options.plugins || [], content, filename, map)) | ||
/** Something went wrong, do nothing */ | ||
.catch(e => { | ||
console.error(e.message) | ||
return { code: content, map } | ||
}) | ||
if (options && options.plugins) { | ||
return process(options.plugins, content, filename, map) | ||
} | ||
try { | ||
/** If not, look for a postcss config file */ | ||
options = await postcssLoadConfig(options, options.configFilePath) | ||
} catch (e) { | ||
/** Something went wrong, do nothing */ | ||
console.error(e.message) | ||
return { code: content, map } | ||
} | ||
return process(options.plugins || [], content, filename, map) | ||
} |
const pug = require('pug') | ||
module.exports = function({ content, filename, options }) { | ||
module.exports = ({ content, filename, options }) => { | ||
options = { | ||
@@ -5,0 +5,0 @@ doctype: 'html', |
@@ -5,3 +5,3 @@ const sass = require('node-sass') | ||
module.exports = function({ content, filename, options }) { | ||
module.exports = ({ content, filename, options }) => { | ||
options = { | ||
@@ -26,2 +26,3 @@ includePaths: getIncludePaths(filename), | ||
map: result.map ? result.map.toString() : undefined, | ||
dependencies: result.stats.includedFiles, | ||
}) | ||
@@ -28,0 +29,0 @@ }, |
@@ -5,3 +5,3 @@ const stylus = require('stylus') | ||
module.exports = function({ content, filename, options }) { | ||
module.exports = ({ content, filename, options }) => { | ||
options = { | ||
@@ -8,0 +8,0 @@ includePaths: getIncludePaths(filename), |
const { readFile } = require('fs') | ||
const { resolve, dirname } = require('path') | ||
const transformers = {} | ||
const CWD = process.cwd() | ||
const PATHS = { | ||
CWD, | ||
MODULES: resolve(CWD, 'node_modules'), | ||
} | ||
const LANG_DICT = new Map([ | ||
@@ -18,9 +12,3 @@ ['postcss', 'css'], | ||
exports.aliasOverrides = { | ||
sass: { | ||
indentedSyntax: true, | ||
}, | ||
} | ||
exports.throwError = msg => { | ||
const throwError = msg => { | ||
throw new Error(`[svelte-preprocess] ${msg}`) | ||
@@ -30,18 +18,6 @@ } | ||
exports.throwUnsupportedError = (lang, filename) => | ||
exports.throwError( | ||
`Unsupported script language '${lang}' in file '${filename}'`, | ||
) | ||
throwError(`Unsupported script language '${lang}' in file '${filename}'`) | ||
exports.isFn = maybeFn => typeof maybeFn === 'function' | ||
/** Gets a pattern for mathing <(tag) (attrs="values")>(content)</tag> */ | ||
exports.getTagPattern = type => | ||
new RegExp(`<${type}([\\s\\S]*?)>([\\s\\S]*?)<\\/${type}>`) | ||
/** Replace a string with another value by slicing it based on a regexp match */ | ||
exports.sliceReplace = (match, str, replaceValue) => | ||
str.slice(0, match.index) + | ||
replaceValue + | ||
str.slice(match.index + match[0].length) | ||
exports.resolveSrc = (importerFile, srcPath) => | ||
@@ -59,15 +35,13 @@ resolve(dirname(importerFile), srcPath) | ||
exports.parseAttributes = attrsStr => | ||
attrsStr | ||
.split(/\s+/) | ||
.filter(Boolean) | ||
.reduce((acc, attr) => { | ||
const [name, value] = attr.split('=') | ||
acc[name] = value ? value.replace(/['"]/g, '') : true | ||
return acc | ||
}, {}) | ||
exports.addLanguageAlias = entries => | ||
entries.forEach(entry => LANG_DICT.set(...entry)) | ||
/** Paths used by preprocessors to resolve @imports */ | ||
exports.getIncludePaths = fromFilename => | ||
[ | ||
process.cwd(), | ||
fromFilename.length && dirname(fromFilename), | ||
resolve(process.cwd(), 'node_modules'), | ||
].filter(Boolean) | ||
exports.getLanguage = (attributes, defaultLang) => { | ||
@@ -91,9 +65,3 @@ let lang = defaultLang | ||
/** Paths used by preprocessors to resolve @imports */ | ||
exports.getIncludePaths = fromFilename => | ||
[ | ||
PATHS.CWD, | ||
fromFilename.length && dirname(fromFilename), | ||
PATHS.MODULES, | ||
].filter(Boolean) | ||
const TRANSFORMERS = {} | ||
@@ -106,10 +74,10 @@ exports.runTransformer = (name, options, { content, filename }) => { | ||
try { | ||
if (!transformers[name]) { | ||
transformers[name] = require(`./transformers/${name}.js`) | ||
if (!TRANSFORMERS[name]) { | ||
TRANSFORMERS[name] = require(`./transformers/${name}.js`) | ||
} | ||
return transformers[name]({ content, filename, options }) | ||
return TRANSFORMERS[name]({ content, filename, options }) | ||
} catch (e) { | ||
exports.throwError(`Error transforming '${name}'. Message:\n${e.message}`) | ||
throwError(`Error transforming '${name}'. Message:\n${e.message}`) | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
26918
19
400
221
1