aboutsummaryrefslogtreecommitdiff
path: root/src/linker.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-06-01 20:49:49 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-06-01 20:49:49 -0700
commitee6643ce8b8b3ac32d5ba71d2617b38bb03379af (patch)
tree728dd42e5c3bfb7272465610326868113f945a88 /src/linker.zig
parent38f1eb07012eaf0e09400ba06d06fe15007a9022 (diff)
downloadbun-ee6643ce8b8b3ac32d5ba71d2617b38bb03379af.tar.gz
bun-ee6643ce8b8b3ac32d5ba71d2617b38bb03379af.tar.zst
bun-ee6643ce8b8b3ac32d5ba71d2617b38bb03379af.zip
wip
Former-commit-id: a6bc130918f63bfbeac220f4e1fa55f08197e1c1
Diffstat (limited to 'src/linker.zig')
-rw-r--r--src/linker.zig75
1 files changed, 47 insertions, 28 deletions
diff --git a/src/linker.zig b/src/linker.zig
index 26eed096d..9b5359481 100644
--- a/src/linker.zig
+++ b/src/linker.zig
@@ -24,6 +24,7 @@ const resolve_path = @import("./resolver/resolve_path.zig");
const _bundler = @import("./bundler.zig");
const Bundler = _bundler.Bundler;
const ResolveQueue = _bundler.ResolveQueue;
+const Runtime = @import("./runtime.zig").Runtime;
pub const Linker = struct {
allocator: *std.mem.Allocator,
@@ -56,7 +57,7 @@ pub const Linker = struct {
.resolve_queue = resolve_queue,
.resolver = resolver,
.resolve_results = resolve_results,
- .runtime_source_path = fs.joinAlloc(allocator, &[_]string{"__runtime.js"}) catch unreachable,
+ .runtime_source_path = fs.absAlloc(allocator, &([_]string{"__runtime.js"})) catch unreachable,
};
}
@@ -66,11 +67,18 @@ pub const Linker = struct {
return RequireOrImportMeta{};
}
+ // pub const Scratch = struct {
+ // threadlocal var externals: std.ArrayList(u32) = undefined;
+ // threadlocal var has_externals: std.ArrayList(u32) = undefined;
+ // pub fn externals() {
+
+ // }
+ // };
// This modifies the Ast in-place!
// But more importantly, this does the following:
// - Wrap CommonJS files
pub fn link(linker: *Linker, file_path: Fs.Path, result: *Bundler.ParseResult) !void {
- var needs_runtime = false;
+ var needs_runtime = result.ast.uses_exports_ref or result.ast.uses_module_ref or result.ast.runtime_imports.hasAny();
const source_dir = file_path.name.dir;
var externals = std.ArrayList(u32).init(linker.allocator);
@@ -78,23 +86,46 @@ pub const Linker = struct {
switch (result.loader) {
.jsx, .js, .ts, .tsx => {
for (result.ast.import_records) |*import_record, record_index| {
+ if (strings.eqlComptime(import_record.path.text, Runtime.Imports.Name)) {
+ import_record.path = try linker.generateImportPath(
+ source_dir,
+ linker.runtime_source_path,
+ );
+ result.ast.runtime_import_record_id = @truncate(u32, record_index);
+ result.ast.needs_runtime = true;
+ continue;
+ }
+
if (linker.resolver.resolve(source_dir, import_record.path.text, import_record.kind)) |*resolved_import| {
if (resolved_import.is_external) {
externals.append(@truncate(u32, record_index)) catch unreachable;
+ continue;
}
+
linker.processImportRecord(
// Include trailing slash
file_path.text[0 .. source_dir.len + 1],
resolved_import,
import_record,
) catch continue;
- import_record.wrap_with_to_module = resolved_import.shouldAssumeCommonJS(import_record);
- if (import_record.wrap_with_to_module) {
- if (!linker.any_needs_runtime) {
- linker.any_needs_runtime = true;
- }
- needs_runtime = true;
+
+ // If we're importing a CommonJS module as ESM
+ // We need to do the following transform:
+ // import React from 'react';
+ // =>
+ // import {_require} from 'RUNTIME_IMPORTS';
+ // import * as react_module from 'react';
+ // var React = _require(react_module).default;
+ // UNLESS it's a namespace import
+ // If it's a namespace import, assume it's safe.
+ // We can do this in the printer instead of creating a bunch of AST nodes here.
+ // But we need to at least tell the printer that this needs to happen.
+ if (import_record.kind == .stmt and !import_record.contains_import_star and resolved_import.shouldAssumeCommonJS(import_record)) {
+ import_record.wrap_with_to_module = true;
+ result.ast.needs_runtime = true;
}
+
+ Output.println("{s} ({s}): CommonJS? {d}", .{ import_record.path.text, @tagName(resolved_import.module_type), @boolToInt(resolved_import.shouldAssumeCommonJS(import_record)) });
} else |err| {
switch (err) {
error.ModuleNotFound => {
@@ -138,23 +169,7 @@ pub const Linker = struct {
},
else => {},
}
-
- // Step 2.
-
result.ast.externals = externals.toOwnedSlice();
-
- if (needs_runtime) {
- std.debug.assert(!result.ast.needs_runtime);
- result.ast.runtime_import_record = ImportRecord{
- .path = try linker.generateImportPath(
- source_dir,
- linker.runtime_source_path,
- ),
- .range = logger.Range.None,
- .kind = .internal,
- };
- result.ast.needs_runtime = true;
- }
}
const ImportPathsList = allocators.BSSStringList(512, 128);
@@ -189,20 +204,24 @@ pub const Linker = struct {
},
.absolute_url => {
+ var base = linker.fs.relativeTo(source_path);
+ if (strings.lastIndexOfChar(base, '.')) |dot| {
+ base = base[0..dot];
+ }
+
const absolute_url = try relative_paths_list.append(
try std.fmt.allocPrint(
&relative_path_allocator.allocator,
- "{s}{s}{s}{s}",
+ "{s}{s}{s}",
.{
linker.options.public_url,
- pathname.dir,
- pathname.base,
+ base,
absolute_pathname.ext,
},
),
);
- return Fs.Path.initWithPretty(absolute_url, pretty);
+ return Fs.Path.initWithPretty(absolute_url, absolute_url);
},
else => unreachable,