diff --git a/package-lock.json b/package-lock.json index 11e7820d..913b8a27 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "husky": "^9.1.7", "jsdom": "24.0.0", "lint-staged": "^15.5.0", + "magic-string": "^0.30.21", "prettier": "^3.6.2", "sinon": "^21.0.0", "tap-diff": "^0.1.1", @@ -1147,9 +1148,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, @@ -4930,6 +4931,16 @@ "yallist": "^3.0.2" } }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", diff --git a/package.json b/package.json index cceb4663..6141160e 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "husky": "^9.1.7", "jsdom": "24.0.0", "lint-staged": "^15.5.0", + "magic-string": "^0.30.21", "prettier": "^3.6.2", "sinon": "^21.0.0", "tap-diff": "^0.1.1", diff --git a/src/lib/precompiler/precompiler.js b/src/lib/precompiler/precompiler.js index c29e05ad..7552b20f 100644 --- a/src/lib/precompiler/precompiler.js +++ b/src/lib/precompiler/precompiler.js @@ -17,6 +17,7 @@ import parser from '../templateparser/parser.js' import generator from '../codegenerator/generator.js' +import MagicString from 'magic-string' export default (source, filePath, mode) => { if ( @@ -26,12 +27,9 @@ export default (source, filePath, mode) => { /\{.*?template\s*:\s*(['"`])((?:\\?.)*?)\1.*?\}/s.test(source) // object with template key ) { const templates = source.matchAll(/(? { // Only process if it looks like a Blits template if (templateContent.match(/^\s*(|<[A-Za-z][^>]*>)/s)) { - const templateStartIndex = template.index + offset + // Use original indices - MagicString handles position tracking automatically + const templateStartIndex = template.index const templateEndIndex = templateStartIndex + template[0].length // Parse the template @@ -58,16 +57,26 @@ export default (source, filePath, mode) => { (fn) => fn.toString() )}], context: {}}` - offset += replacement.length - template[0].length - - newSource = - newSource.substring(0, templateStartIndex) + - replacement + - newSource.substring(templateEndIndex) + // MagicString tracks all changes automatically, no offset needed + s.overwrite(templateStartIndex, templateEndIndex, replacement) } } } - return newSource + + const newSource = s.toString() + + if (newSource !== source) { + const fileName = filePath.split(/[\\/]/).pop() + return { + code: newSource, + map: s.generateMap({ + hires: true, + source: fileName, + includeContent: true, + file: fileName, + }), + } + } } return source } diff --git a/src/lib/reactivityguard/computedprops.js b/src/lib/reactivityguard/computedprops.js index 8f3248f1..90ced535 100644 --- a/src/lib/reactivityguard/computedprops.js +++ b/src/lib/reactivityguard/computedprops.js @@ -213,7 +213,12 @@ export default (code) => { modifiedCode = modifiedCode.replace(mod.original, mod.replacement) } - return { code: modifiedCode } + // Returning code without a source map + // Vite will automatically chain this with the next plugin's source map (preCompiler) + return { + code: modifiedCode, + map: { mappings: '' }, + } } return null diff --git a/vite/preCompiler.js b/vite/preCompiler.js index 176bb96d..e4d59828 100644 --- a/vite/preCompiler.js +++ b/vite/preCompiler.js @@ -32,12 +32,22 @@ export default function () { // we should only precompile .blits, .js and .ts files if ( - fileExtension === '.js' || - fileExtension === '.ts' || - fileExtension === '.blits' || - fileExtension === '.mjs' + filePath.indexOf('node_modules') === -1 && + (fileExtension === '.js' || + fileExtension === '.ts' || + fileExtension === '.blits' || + fileExtension === '.mjs') ) { - return compiler(source, filePath, config.mode) + const result = compiler(source, filePath, config.mode) + + if (typeof result === 'object') { + return { + code: result.code, + map: result.map, + } + } + // No transformation needed - return null so Vite knows no changes were made + return null } // vite expects null if there is no modification