-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Add possibility to disable code splitting / chunks generation #2756
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
Comments
This is not a documentation issue. It is not possible to build several overlapping targets in the same build without code-splitting. One core principle in Rollup's architecture is at the moment that each module exists only once. I see however the benefit of being able to do that, which would be performance: As we are sharing the same input options, shared modules do not need to be loaded, transformed or parsed again. In the future, we might consider adding an option to mark entry points as "standalone" to the effect that those entry points are handled in a separate build phase that shares the same parsed modules. |
@lukastaegert yeah, this turned out to cause a lot of difficulties for me. For server code, I don't need chunks. Array in config makes it hard to work with plugins as they run multiple times with different context. Same for browser, I can't have an
*changed issue to a feature request |
@lukastaegert thoughts on the state of this one? |
At the moment this is lower priority. I would prefer to put more work in a cache plugin API that could be utilised by the CLI to share information between builds in an array of inputs. If this is done, it could be possible to reintroduce this as a CLI feature. |
IMHO it would be more intuitive to simply disable the code-splitting feature for module formats for which this feature isn't supported and just build the modules without chunks. Maybe with a warning or by requiring a force flag? |
When trying to build a
Obviously, this is a library for npm so I don't want or need code splitting in this context - I just need maximum import compatibility. export default {
input: `src/index.ts`,
preserveModules: true,
output: {
format: 'umd',
dir: './dist'
},
external: [],
watch: {
include: 'src/**',
},
plugins: [
json(),
typescript({ useTsconfigDeclarationDir: true }),
commonjs(),
resolve(),
sourceMaps(),
],
} |
The whole point of |
You're right, I mistakenly thought webpack wouldn't read import/export syntax in node_modules |
I've just hit the same roadblock. I'm building a serverless application in which I want standalone files (bundles) in the end. In my case I don't want any imports, I want all the required code in the same file: one source file = one completely standalone compiled file. X input files = X outputs files. Currently it seems that with multiple inputs the bundler... doesn't actually bundle everything. A semi-working solution is to export multiple configs from rollup config, i.e. Another solution is to put all these shared modules (output chunks) into a separate folder and include them with every single serverless function. You end up including unneeded code in your serverless functions. So this is a suboptimal solution too. {
input: [ { function1: 'src/function1.js', function2: 'src/function2.js' } ],
output: {
entryFileNames: '[name].js',
chunkFileNames: 'includes/[hash].js',
}
} When deploying you have to copy this entire |
See also #2398. |
This is making it difficult to use Rollup for my browser extension. I want to use Rollup because I'm working around a bug that prevents me from using ES6 modules natively in Firefox extension content scripts; the ability to use However, if I want to build multiple files (e.g. different content scripts that operate on separate domains) by passing an array to I realize that disabling code splitting still wouldn't be a perfect solution, because shared code will be duplicated between the generated bundles, but it seems like it'd be the best way for my use-case - other than maybe generating an |
Also would like to see this made possible. It'd let me get around Firefox not supporting |
I'm having the same issue. I'm using Vite, and I need to ensure that every ounce of JavaScript ends up in a single file, with no This was working awhile back for Vite, but then a change was made there that is now resulting in a |
@richardtallent you can try this in the vite config file. It works for me. build: {
rollupOptions: {
output: {
manualChunks: {}
}
}
} |
Hi @HongSiyuan, Thanks! Yes, we were able to update vite-plugin-singlefile with a similar option for |
If we have more components, some start to get excluded and / or rollup complains about needed to use chunks. This work around seems to preserve the previous behavior. See rollup/rollup#2756. Also split the glob pattern to be a little easier to read?
I also have a use-case where I am bundling a Web Component that is dynamically imported on the client ( using Ideally I would use IIFE or UMD, but I get the "not compatible with code-splitting" error, even though I'm explicitly not wanting to code split. Is there a way I can see what's trying to be code split so I can work around it? Is there any custom plugin hacks that will get around this? All the hooks I can see go all the way up to individual import processing, then skip straight to writing chunks, without any opportunity to customise the chunk generation process. I've spent most of the week touring all of the bundlers trying to get away from Webpack, and Rollup by far is the most extendable I've seen so far. I can't switch all our stuff over to it unless it has this feature. |
Nice find. Setting |
I'm building a chrome extension based on antfu/vitesse-webext now The extension has two content scripts for different website that has same dependency . my build config rollupOptions: {
input: {
a: r('src/contentScripts/a.ts'),
b: r('src/contentScripts/b.ts'),
},
output: {
entryFileNames({ name }) {
return `${name}.global.js`
},
},
}, rollup always chunk the shared dependency , so content script can't work because it #a.global.js
import {s as e} from"./chunk.js"; how to disable chunk and build two standalone js file , is there some hacking solution ? @lukastaegert I hope to raise the priority because it has been two years .. thanks |
I found a way to split scripts, one for a main.js script and another script for each page: import { basename } from 'path'
// import rimraf from 'rimraf'
import { build } from 'vite'
import glob from 'glob'
import { fileURLToPath, URL } from 'url'
import includeHTMLPlugin from './plugins/vite-plugin-include-html.js'
const __dirname = fileURLToPath(new URL('.', import.meta.url))
const pages = glob.sync('./**/*.html', {
ignore: [
'./node_modules/**',
'./partials/**',
'./dist/**',
]
}).map(file => [
// Remove the extension to create a JavaScript file with the name of the page
basename(file).replace(/\.[^.]+$/, ''),
// This expands the relative paths to absolute paths, so e.g.
// src/nested/foo becomes /home/username/dev/projectname/src/nested/foo.js
fileURLToPath(new URL(file, import.meta.url))
])
// console.log(pages)
async function buildPackages() {
// await rimraf("./dist")
for (const [filename, filepath] of pages) {
console.log('Building', filepath)
await build({
publicDir: false,
plugins: [
includeHTMLPlugin(`${__dirname}/partials/`)
],
build: {
rollupOptions: {
input: {
[filename]: filepath, // Page script
main: 'main.js', // Shared main file
},
output: {
entryFileNames: "js/[name]-[hash].js",
},
},
emptyOutDir: false
},
configFile: false,
})
}
}
buildPackages() Hope it helps somehow. |
Removing code splitting in dev mode does not seem to work. Is there any other solution for this? It fetches like 10 js chunks in dev mode but not in production mode. |
Related issue: #5212 |
Releted issue: vite #1683 |
Hey team, any updates on this? Is this likely ever to be a thing/on the roadmap? Anyone have success achieving this by using other build tools? Thanks in advance. |
fwiw I moved away from vite in favor of bun, and was able to achieve this by way of having 2 separate builds and implementing the build programmatically: |
When trying to build in lib mode - @jim-spot's solution above doesn't work with vite. When exporting the array, build fails with below error:
I was able to tweak the solutions proposed by @yashspr and @nicholasdavidbrown for lib mode by create a
Simple run |
@rahulbhanushali any chance you might share the config that didn't work for you? Also would be curious to know the version you were on. We've been using that config without fail on many projects now. |
Any progress ? |
Has anyone figured out how to use this multiple entry points config but with shared vendor chunks? So for example: Widget 1 and Widget 2 both use React, so a build script would generate the following files:
I really need this type of config because I'm trying to upgrade from this type of webpack setup: https://gist.github.com/Akryum/ece2ca512a1f40d70a1d467566783219 |
I was able to write a small plugin that will disable code-splitting / chunking a specific files out. The idea is the same as this guy, but with some better support for any file type (hopefully?) that your existing config can parse. import path from 'path';
const disableChunks = (targets = []) => {
/** @type{import('rollup').Plugin} */
const plugin = {
name: 'disable-chunks',
async resolveId(source, importer, options) {
const resolved = await this.resolve(source, importer, options);
if (resolved && targets.some(file => resolved.id.includes(file))) {
return `${resolved.id}?unique=${Math.random()}`;
}
},
load(id) {
const regex = /(\?unique=.*)$/;
if (regex.test(id)) {
return this.load({ id: id.replace(regex, '') });
}
},
generateBundle(options, bundle) {
const nonEntryChunks = Object.values(bundle).filter(({ isEntry }) => !isEntry);
if (nonEntryChunks.length > 0) {
const moduleIds = new Set(
nonEntryChunks.map(({ moduleIds }) => moduleIds).flat()
.map(absPath => path.relative('.', absPath)),
);
throw new Error(`Found non-entry chunks: ${Array.from(moduleIds).join(', ')}`);
}
},
};
return plugin;
}; Usage: // rollup.config.mjs
export default defineConfig([{
input: ['src/index1.ts', 'src/index2.ts'],
output: {
dir: 'dist',
},
plugins: [
disableChunks(['src/shared.ts']),
typescript({ module: 'ESNext' }),
],
}]);
// src/shared.ts
export default { hello: 'world' };
// src/index1.ts
import Shared from './shared';
console.log('index1.ts', Shared);
// src/index2.ts
import Shared from './shared';
console.log('index2.ts', Shared);
// dist/index1.js
var Shared = { hello: 'world' };
console.log('index1.ts', Shared);
// dist/index2.js
var Shared = { hello: 'world' };
console.log('index2.ts', Shared); I hope this helps someone. I didn't put too much effort into figuring out if its possible to auto detect the targets. |
My project is currently using Webpack, and I am trying to migrate to Vite with multiple entry points. While running the Vite build command, it is creating chunks. Is there any supported way to stop creating chunk files, or any suggestions? I already tried using |
There has been no progress until 2024. import { PluginOption } from 'vite';
import path from 'node:path';
/**
* 生成一段能够插入HTML的Script标签,用于注册Service Worker
* @param filename
* @param scope
* @returns
*/
function generateSWScript(src: string, scope = '/', isModule = false): string {
return `<script id=service-worker>
if('serviceWorker' in navigator){
navigator.serviceWorker.register('${src}', {
scope: '${scope}',
${isModule ? ", type: 'module'" : ''}
})
}
</script>`;
}
/**
* Service Worker Vite插件,用于打包项目中的单个sw.js
* @param file sw.ts在项目中的位置
* @param scope 手动指名的作用域
* @param option.renderFile 插入到HTML中实际注册的文件地址.
* @param option.scope 指定sw注册时的作用域
* @param option.devPort 本地服务器端口
* @returns
*/
export default function (
file: string,
option = {
output: '',
renderFile: '',
scope: '',
}
): PluginOption {
const { renderFile, scope, output } = option;
const sourceFile = renderFile.replace('.js', path.extname(file));
return {
name: 'vite-plugin-service-worker',
config() {
return {
build: {
rollupOptions: {
output: {
manualChunks: {
[file]: [file],
},
},
},
},
};
},
async buildStart() {
if (this.meta.watchMode) {
return;
}
this.emitFile({
type: 'chunk',
fileName: output || 'assets/sw.js',
id: file,
});
},
configureServer(server) {
server.middlewares.use(async (req, _, next) => {
if (req.url === sourceFile) {
req.url = path.join(server.config.base || '', file);
}
next();
});
},
transformIndexHtml(html, ctx): string {
const command = ctx.server?.config.command;
const isServe = command === 'serve';
return html.replace(
'</body>',
` ${generateSWScript(isServe ? sourceFile : renderFile, scope, isServe)}\n </body>`
);
},
};
} |
Any updates? It's really important and required urgently. The thread live actively from 2019 tells anything. |
Firstly, doing this only for specific targets doesn't do much. You practically need to do it for all non-entry modules, thereby separating their dependency tries. |
It's been half a decade since this issue was raised. I think it's safe to say it won't be resolved any time soon. As someone new to browser extensions, I'm wondering if others here might help clarify if this issue also appears when using Webpack? Some of the comments suggest that Webpack doesn't have these issues. If this is true, then perhaps using RSBuild in favor of Vite would be the way to go. Can anyone confirm? |
What I'd like everyone making comments on a lack of progress on this to understand is that Rollup (core) is currently maintained by one person who holds this project on his shoulders in his free time between family and life responsibilities. This isn't anyone's full time job. Instead of making comments on progress, step up and contribute. I will nuke from orbit any further replies that mention progress. Step up, or step out. |
Feature Use Case
The code above will create chunks when both files have same imports. Sometimes it's not desired, for example when each file needs to be self-contained (serverless). It would be nice to be able to turn code splitting off.
Using array in rollup config is not desired as it creates difficulties in working with plugins.
Feature Proposal
Add config option to turn code splitting feature off.
The text was updated successfully, but these errors were encountered: