You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rollup打包顺序问题咨询:同步脚本代码位置不符预期

Why Rollup Puts Imported Code at the Top & How to Fix It

Hey there! Let's clear up this confusion for you. First off, this isn't a configuration bug—it's actually Rollup's default behavior tied to how ES modules work. Here's what's going on, plus solutions to fit your use case:

What's Happening Under the Hood

Rollup uses static analysis of ES modules to optimize your code (like tree-shaking). By design, ES modules require all static imports to be resolved and executed before the top-level code of the importing module runs. That's why Rollup moves the code from maths.js to the start of your bundled file—it's following the ES module execution order.

In your example, this causes a problem because maths.sum tries to reference numbers.base, but numbers.base hasn't been defined yet (since Rollup runs maths.js code first).

Solutions to Match Your Expected Behavior

Option 1: Refactor Code to Avoid Top-Level Dependencies

The cleanest fix is to adjust your modules so they don't rely on top-level variables from other modules. Instead, pass dependencies as arguments or use functions to delay evaluation:

Modified maths.js

let maths = {};
// Accept base as a parameter instead of relying on an external variable
maths.sum = function(x, y, base) { 
  return base + x + y; 
}
export {maths};

Modified index.js

/** * License ... */
let numbers = {};
numbers.property = "This is a static variable";
numbers.base = 1000;

// Module maths
import {maths} from "./maths";
numbers.maths = maths;

// Testing
// Pass numbers.base as an argument
console.log(numbers.maths.sum(10, 20, numbers.base))

This way, the order of bundled code doesn't matter—you're explicitly passing the value when you need it.

Option 2: Use Dynamic Imports for Execution Order Control

If you absolutely need the imported module's code to run at the exact spot of your import statement, switch to dynamic imports. Unlike static imports, dynamic imports execute when the code reaches that line:

Updated index.js

/** * License ... */
let numbers = {};
numbers.property = "This is a static variable";
numbers.base = 1000;

// Module maths (dynamic import)
import("./maths").then(({maths}) => {
  numbers.maths = maths;
  // Testing
  console.log(numbers.maths.sum(10, 20))
});

Note: Dynamic imports are asynchronous, so your code inside the .then() will run after the module loads. If you need synchronous execution, you can wrap this in an async function and use await.

Option 3: Preserve Module Structure (Multiple Output Files)

If you don't mind outputting multiple files instead of a single bundle, use the preserveModules option in your rollup.config.js. This keeps each module as a separate file, so the import statement stays in place and runs in the order you expect:

rollup.config.js

export default {
  input: 'index.js',
  output: {
    dir: 'dist',
    format: 'es', // Or 'cjs' for CommonJS
    preserveModules: true
  }
};

When you run Rollup, it will output dist/index.js and dist/maths.js, with the import in index.js remaining at its original position. The browser (or Node.js) will handle executing the modules in the correct order.

Key Takeaway

Rollup's default behavior aligns with ES module standards, which prioritize resolving all imports before executing the parent module. To fix your issue, either refactor your code to avoid cross-module top-level dependencies, use dynamic imports for execution order control, or preserve the module structure with preserveModules.

内容的提问来源于stack exchange,提问作者The Devman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 11:07:30