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

serve and sass compiler not detecting changes in imported scss that previously caused an error (beta 2 regression) #6025

Open
robertvanhoesel opened this issue Mar 19, 2021 · 3 comments

Comments

@robertvanhoesel
Copy link

🐛 bug report

I'm using a simple project with an index.html, linking a style.scss that imports other scss files and running parcel serve. When the sass compiler encounters an error in one if the imported scss files, it will output the error to the console.

After fixing the error and saving the file, the compiler does not notice the change and nothing happens.

This is a regression from 2.0 beta 1, where it successfully picked up the fix and restarted compilation.

🎛 Configuration (.babelrc, package.json, cli command)

parcel serve index.html --open --no-cache

// package.json
{
	//....
   "scripts": {
    "start": "parcel serve index.html --open --no-cache",
    "build": "parcel build index.html"
  },
  "dependencies": {},
  "devDependencies": {
    "@babel/core": "7.13.8",
    "parcel": "2.0.0-beta.2",
    "sass": "^1.32.8",
    "typescript": "4.2.3"
  },
  "resolutions": {
    "@babel/preset-env": "7.13.8"
  },
}

🤔 Expected Behavior

When using serve, an imported scss file into an other scss file, and encountering a sass compilation error, I expect it to recompile after I fix my change.

😯 Current Behavior

The new change (fix) in the broken file is not detected.

🔦 Context

  • This only happens on imported scss, when I break and fix the primary referenced scss file (the one included in index.html) it works fine.
  • Also, If is save the primary scss after fixing imported scss it does pick up the new fixed file.
  • I can only reproduce this behavior in scss, when breaking i.e. an imported ts file and fixing it, serve continues.
  • Running serve with or without --no-cache flag makes no difference

This issue is especially noticeable when having auto save enabled in the IDE, it will save WIP code (i.e. midway typing a line) code and trigger the compilation — which usually is fine, but not if have have to restart serve every time it compiles en encounters an error.

💻 Code Sample

Full repro continue-serve-after-error-beta2-repro.zip

Both beta 1 and beta 2 included for reference.

🌍 Your Environment

Software Version(s)
Parcel 2.0.0-beta2
Node v14.5.0
npm/Yarn yarn
Operating System os x
@robertvanhoesel
Copy link
Author

This might be related to #5132 although I start without cache.

@benfrain
Copy link

I get this issue without an error. Any scss file imported from another fails to register a change. Have to continually go to main file and click save to force a compile and update.

@wibjorn
Copy link

wibjorn commented Apr 30, 2021

Looking over the @parcel/transformer-sass code a little bit, pieced together a few clues, but still don't have a proper solution. Here's what I've found.

  • errors that break the sass render function prevent parcel from adding included assets. Meaning it does not watch them.
  • successful sass builds return result.data.includedFiles which parcel adds and watches. The equivalent does not seem to exist for failures.
  • I've set up a small repo here to the issue easily: codespace: https://wibjorn-crispy-umbrella-3qv6.github.dev/ repo: https://github.com/wibjorn/crispy-umbrella (repro steps in readme)
  • in the catch you can do some (unsatisfactory) workarounds to the the watch task to work.
    • remove rethrow err. 💀
    • add css = '' 💀 This allows us to escape an internal error that happens we we don't throw but there is no content. Causes parcel build to pass when it should fail.
    • asset.addIncludedFile(err.file); - If we do this, in conjunction with the above things, the error causing partial (non-entry) file is watched. If you do this, but also throw, it still does not watch that file.
    • see ⭐
	async transform({ asset, options, config, resolve, logger }) {
		let rawConfig = config !== null && config !== void 0 ? config : {};
		let sassRender = (0, _util().promisify)(_sass().default.render.bind(_sass().default));
		let css;

		try {
			let code = await asset.getCode();
			let result = await sassRender({
				...rawConfig,
				file: asset.filePath,
				data: rawConfig.data ? rawConfig.data + _os().EOL + code : code,
				importer: [
					...rawConfig.importer,
					resolvePathImporter({
						asset,
						resolve,
						includePaths: rawConfig.includePaths,
						options
					})
				],
				indentedSyntax:
					typeof rawConfig.indentedSyntax === 'boolean'
						? rawConfig.indentedSyntax
						: asset.type === 'sass'
			});
			css = result.css;

			for (let included of result.stats.includedFiles) {
                                // ⭐ only if the build passes are includedFiles added to the asset.
                                // ⭐ this seems to be one source of the problem?
				if (included !== asset.filePath) {
					asset.addIncludedFile(included);
				}
			}

			if (result.map != null) {
				let map = new (_sourceMap().default)(options.projectRoot);
				map.addRawMappings(JSON.parse(result.map));
				asset.setMap(map);
			}
		} catch (err) {
		        // ⭐Here, if you don't throw, you can watch the file for changes.
			asset.addIncludedFile(err.file);

			// Adapt the Error object for the reporter.
			err.fileName = err.file;
			err.loc = {
				line: err.line,
				column: err.column
			};
			// ⭐ Escape an internal error.
			css = '';
			// ⭐ Removes throw and uses logger.
			 // ⭐But `parcel build` will pass. Not good.
			logger.error(err);
		}

		asset.type = 'css';
		asset.setCode(css);
		return [asset];
	}
});

As you can see this isn't a solution, but I think it adds some context to the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants