如何让Eleventy在--serve模式下正确更新SCSS编译结果?
问题
我有一个使用SCSS的简单Eleventy项目,文件结构如下:
src ├─ styles │ ├─ components │ │ ├─ _buttons.scss │ │ ├─ _forms.scss │ ├─ site.scss
运行--serve CLI选项时,初始构建可正确生成_site/styles/site.css文件。但修改components/*.scss文件时,CLI提示文件已变更,但生成的site.css完全没有更新。不过直接修改site.scss文件或重启--serve进程后,就能正确生成CSS。
以下是我的eleventy.js文件:
const sass = require('sass'); const path = require('node:path'); module.exports = function (eleventyConfig) { eleventyConfig.addTemplateFormats('scss'); eleventyConfig.addExtension('scss', { outputFileExtension: 'css', compile: async function (inputContent, inputPath) { let parsedPath = path.parse(inputPath); let result = sass.compileString(inputContent, { loadPaths: [parsedPath.dir || '.', this.config.dir.includes], }); return async (data) => result.css; }, }); return { dir: { input: 'src' }, }; };
解决方法
问题根源是当前的SCSS扩展没有让Eleventy追踪到主SCSS文件的依赖(也就是components/下的_*.scss文件)。初始编译后,依赖文件变更时,Eleventy不知道需要重新触发主文件的编译。
需要做两个关键修改:
- 改用
sass.compile替代sass.compileString,让Sass自动解析并返回所有依赖文件的列表 - 通过
this.addDependencies把依赖文件注册给Eleventy,让它监听这些文件的变更
修改后的eleventy.js代码如下:
const sass = require('sass'); const path = require('node:path'); module.exports = function (eleventyConfig) { eleventyConfig.addTemplateFormats('scss'); eleventyConfig.addExtension('scss', { outputFileExtension: 'css', compile: async function (inputContent, inputPath) { // 直接编译文件路径,自动解析@import的依赖 let result = sass.compile(inputPath, { loadPaths: [path.dirname(inputPath), this.config.dir.includes], }); // 注册依赖文件,让Eleventy监听这些文件的变更 this.addDependencies(inputPath, result.loadedUrls.map(url => url.pathname)); return async (data) => result.css; }, }); return { dir: { input: 'src' }, }; };
修改说明:
sass.compile会读取实际文件路径,自动识别所有@import引入的依赖文件,返回的result.loadedUrls包含这些依赖的完整路径this.addDependencies将主SCSS文件和它的依赖文件关联起来,当任意依赖文件变更时,Eleventy会自动重新编译主SCSS文件,生成更新后的CSS
这样修改后,修改components/下的任意SCSS文件,Eleventy都会自动重新生成site.css,无需重启服务或手动修改主SCSS文件。
内容的提问来源于stack exchange,提问作者Chris Barr
相关产品推荐
相关产品推荐

