Hi Team Svelte 👋 First time posting so let me say thank you for all your efforts and for sharing svelte with us all!
Please consider adding plumbing for preprocess dependencies. That is, the ability for svelte preprocessors to report which files were processed. This will allow bundler plugins such as rollup-plugin-svelte and svelte-loader to report these files so that they can be watched. Rollup recently allowed for specifying dependencies to watch (in rollup/rollup#2259) through transform dependencies and webpack's plugin API supports this as well.
In my use, I'm using kaisermann/svelte-preprocess to develop with external files in scss and pug. I'm bundling with rollup, which isn't able to detect when these files change since the rollup input file itself isn't changing. I've found a workaround by defining a plugin just to add these dependencies, but it seems like it should be plumbed through svelte.preprocess instead.
Unfortunately, it looks like this would require a breaking change in the preprocess API. The API currently returns a promise with the preprocessed code. I think for this to work the interface would need to change to return a promise of code and an array of dependencies.
I'm suggesting this,
let preprocessOpts = {
markup: ({ content, filename }) => {
return {
code: '<!-- some HTML -->',
map: {...},
},
style: ({ content, attributes, filename }) => {
return {
code: '/* some CSS */',
map: {...}
};
},
script: ({ content, attributes, filename }) => {
return {
code: '// some JavaScript',
map: {...}
};
}
svelte.preprocess(input, preprocessOpts).then(code => {})
Could be changed to this,
let preprocessOpts = {
markup: ({ content, filename }) => {
return {
code: '<!-- some HTML -->',
map: {...},
dependencies: ['template.pug', 'include.pug']
},
style: ({ content, attributes, filename }) => {
return {
code: '/* some CSS */',
map: {...},
dependencies: ['_mixins.scss', 'styles.scss']
};
},
script: ({ content, attributes, filename }) => {
return {
code: '// some JavaScript',
map: {...},
dependencies: []
};
}
svelte.preprocess(input, preprocessOpts).then(({ code, dependencies }) => {})
My workaround is working for now, and I'm not excited about the breaking change in the returned Promise. Still, this seems like the right place to plumb dependencies through for bundlers.
Thank you for your time and consideration.
This is a great idea! And I don't think it's a breaking change — right now svelte.preprocess doesn't resolve to a string, it resolves to an object with a toString method. The thinking there was that it would eventually support sourcemap composition which would mean returning code and map separately, but it means that we can drop in that dependencies array without breaking any existing apps, which is a happy accident.
Hi @jvmccarthy would you mind sharing what you did to create a work around for this? This is becoming a bit of an issue for me, but I'm curious to try a hack to get around it.
@awenate sorry for taking so long to get back to you. I moved away from this workaround, and now I'm having a hard time finding it. I think I used a glob lib to create a very simple plugin function returning just dependencies so that rollup would rebuild (I believe it was a svelte+rollup workaround). Something like this in rollup.config.js,
const globby = require('globby');
//...
export default {
//...
plugins: [
() => {
return {
dependencies: globby.sync('src/**/*')
};
},
//...
]
}
Both the Rollup plugin and the webpack plugin allow the result of the preprocessor to have an additional key dependencies which is an array of additional paths that should be watched for changes during development.
Most helpful comment
This is a great idea! And I don't think it's a breaking change — right now
svelte.preprocessdoesn't resolve to a string, it resolves to an object with atoStringmethod. The thinking there was that it would eventually support sourcemap composition which would mean returningcodeandmapseparately, but it means that we can drop in thatdependenciesarray without breaking any existing apps, which is a happy accident.