Skip to content

Commit

Permalink
feat(bake): css, production build, dev separateSSRGraph=false (#14622)
Browse files Browse the repository at this point in the history
Co-authored-by: Jarred Sumner <[email protected]>
Co-authored-by: paperdave <[email protected]>
Co-authored-by: Jarred-Sumner <[email protected]>
  • Loading branch information
4 people authored Oct 27, 2024
1 parent 5237869 commit e93c5ad
Show file tree
Hide file tree
Showing 63 changed files with 3,479 additions and 1,736 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ test/node.js/upstream
.zig-cache
scripts/env.local
*.generated.ts
src/bake/generated.ts

# Dependencies
/vendor
Expand Down
2 changes: 1 addition & 1 deletion src/allocators.zig
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ pub fn BSSMap(comptime ValueType: type, comptime count: anytype, comptime store_
}

// There's two parts to this.
// 1. Storing the underyling string.
// 1. Storing the underlying string.
// 2. Making the key accessible at the index.
pub fn putKey(self: *Self, key: anytype, result: *Result) !void {
self.map.mutex.lock();
Expand Down
79 changes: 0 additions & 79 deletions src/bake/BakeDevSourceProvider.cpp

This file was deleted.

80 changes: 64 additions & 16 deletions src/bake/BakeDevGlobalObject.cpp → src/bake/BakeGlobalObject.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "BakeDevGlobalObject.h"
#include "BakeGlobalObject.h"
#include "JSNextTickQueue.h"
#include "JavaScriptCore/GlobalObjectMethodTable.h"
#include "JavaScriptCore/JSInternalPromise.h"
Expand All @@ -14,34 +14,61 @@ extern "C" void BakeInitProcessIdentifier()
}

JSC::JSInternalPromise*
moduleLoaderImportModule(JSC::JSGlobalObject* jsGlobalObject,
bakeModuleLoaderImportModule(JSC::JSGlobalObject* jsGlobalObject,
JSC::JSModuleLoader*, JSC::JSString* moduleNameValue,
JSC::JSValue parameters,
const JSC::SourceOrigin& sourceOrigin)
{
// TODO: forward this to the runtime?
JSC::VM& vm = jsGlobalObject->vm();
WTF::String keyString = moduleNameValue->getString(jsGlobalObject);
auto err = JSC::createTypeError(
jsGlobalObject,
WTF::makeString(
"Dynamic import should have been replaced with a hook into the module runtime"_s));
"Dynamic import to '"_s, keyString,
"' should have been replaced with a hook into the module runtime"_s));
auto* promise = JSC::JSInternalPromise::create(
vm, jsGlobalObject->internalPromiseStructure());
promise->reject(jsGlobalObject, err);
return promise;
}

extern "C" BunString BakeProdResolve(JSC::JSGlobalObject*, BunString a, BunString b);

JSC::Identifier bakeModuleLoaderResolve(JSC::JSGlobalObject* jsGlobal,
JSC::JSModuleLoader* loader, JSC::JSValue key,
JSC::JSValue referrer, JSC::JSValue origin)
{
Bake::GlobalObject* global = jsCast<Bake::GlobalObject*>(jsGlobal);
JSC::VM& vm = global->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

if (global->isProduction()) {
WTF::String keyString = key.toWTFString(global);
RETURN_IF_EXCEPTION(scope, vm.propertyNames->emptyIdentifier);

ASSERT(referrer.isString());
auto refererString = jsCast<JSC::JSString*>(referrer)->value(global);

BunString result = BakeProdResolve(global, Bun::toString(referrer.getString(global)), Bun::toString(keyString));
return JSC::Identifier::fromString(vm, result.toWTFString(BunString::ZeroCopy));
} else {
JSC::throwTypeError(global, scope, "External imports are not allowed in Bun Bake's dev server. This is a bug in Bun's bundler."_s);
return vm.propertyNames->emptyIdentifier;
}
}

#define INHERIT_HOOK_METHOD(name) \
Zig::GlobalObject::s_globalObjectMethodTable.name

const JSC::GlobalObjectMethodTable DevGlobalObject::s_globalObjectMethodTable = {
const JSC::GlobalObjectMethodTable GlobalObject::s_globalObjectMethodTable = {
INHERIT_HOOK_METHOD(supportsRichSourceInfo),
INHERIT_HOOK_METHOD(shouldInterruptScript),
INHERIT_HOOK_METHOD(javaScriptRuntimeFlags),
INHERIT_HOOK_METHOD(queueMicrotaskToEventLoop),
INHERIT_HOOK_METHOD(shouldInterruptScriptBeforeTimeout),
moduleLoaderImportModule,
INHERIT_HOOK_METHOD(moduleLoaderResolve),
bakeModuleLoaderImportModule,
bakeModuleLoaderResolve,
INHERIT_HOOK_METHOD(moduleLoaderFetch),
INHERIT_HOOK_METHOD(moduleLoaderCreateImportMetaProperties),
INHERIT_HOOK_METHOD(moduleLoaderEvaluate),
Expand All @@ -58,17 +85,16 @@ const JSC::GlobalObjectMethodTable DevGlobalObject::s_globalObjectMethodTable =
INHERIT_HOOK_METHOD(canCompileStrings),
};

DevGlobalObject*
DevGlobalObject::create(JSC::VM& vm, JSC::Structure* structure,
GlobalObject* GlobalObject::create(JSC::VM& vm, JSC::Structure* structure,
const JSC::GlobalObjectMethodTable* methodTable)
{
DevGlobalObject* ptr = new (NotNull, JSC::allocateCell<DevGlobalObject>(vm))
DevGlobalObject(vm, structure, methodTable);
GlobalObject* ptr = new (NotNull, JSC::allocateCell<GlobalObject>(vm))
GlobalObject(vm, structure, methodTable);
ptr->finishCreation(vm);
return ptr;
}

void DevGlobalObject::finishCreation(JSC::VM& vm)
void GlobalObject::finishCreation(JSC::VM& vm)
{
Base::finishCreation(vm);
ASSERT(inherits(info()));
Expand All @@ -77,7 +103,8 @@ void DevGlobalObject::finishCreation(JSC::VM& vm)
extern "C" BunVirtualMachine* Bun__getVM();

// A lot of this function is taken from 'Zig__GlobalObject__create'
extern "C" DevGlobalObject* BakeCreateDevGlobal(DevServer* owner,
// TODO: remove this entire method
extern "C" GlobalObject* BakeCreateDevGlobal(DevServer* owner,
void* console)
{
JSC::VM& vm = JSC::VM::create(JSC::HeapType::Large).leakRef();
Expand All @@ -86,11 +113,11 @@ extern "C" DevGlobalObject* BakeCreateDevGlobal(DevServer* owner,
BunVirtualMachine* bunVM = Bun__getVM();
WebCore::JSVMClientData::create(&vm, bunVM);

JSC::Structure* structure = DevGlobalObject::createStructure(vm);
DevGlobalObject* global = DevGlobalObject::create(
vm, structure, &DevGlobalObject::s_globalObjectMethodTable);
JSC::Structure* structure = GlobalObject::createStructure(vm);
GlobalObject* global = GlobalObject::create(
vm, structure, &GlobalObject::s_globalObjectMethodTable);
if (!global)
BUN_PANIC("Failed to create DevGlobalObject");
BUN_PANIC("Failed to create BakeGlobalObject");

global->m_devServer = owner;
global->m_bunVM = bunVM;
Expand All @@ -115,4 +142,25 @@ extern "C" DevGlobalObject* BakeCreateDevGlobal(DevServer* owner,
return global;
}

extern "C" GlobalObject* BakeCreateProdGlobal(JSC::VM* vm, void* console)
{
JSC::JSLockHolder locker(vm);
BunVirtualMachine* bunVM = Bun__getVM();

JSC::Structure* structure = GlobalObject::createStructure(*vm);
GlobalObject* global = GlobalObject::create(*vm, structure, &GlobalObject::s_globalObjectMethodTable);
if (!global)
BUN_PANIC("Failed to create BakeGlobalObject");

global->m_devServer = nullptr;
global->m_bunVM = bunVM;

JSC::gcProtect(global);

global->setConsole(console);
global->setStackTraceLimit(10); // Node.js defaults to 10

return global;
}

}; // namespace Bake
15 changes: 9 additions & 6 deletions src/bake/BakeDevGlobalObject.h → src/bake/BakeGlobalObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@ struct DevServer; // DevServer.zig
struct Route; // DevServer.zig
struct BunVirtualMachine;

class DevGlobalObject : public Zig::GlobalObject {
class GlobalObject : public Zig::GlobalObject {
public:
using Base = Zig::GlobalObject;

/// Null if in production
DevServer* m_devServer;

template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
return WebCore::subspaceForImpl<DevGlobalObject, WebCore::UseCustomHeapCellType::Yes>(
return WebCore::subspaceForImpl<GlobalObject, WebCore::UseCustomHeapCellType::Yes>(
vm,
[](auto& spaces) { return spaces.m_clientSubspaceForBakeGlobalScope.get(); },
[](auto& spaces, auto&& space) { spaces.m_clientSubspaceForBakeGlobalScope = std::forward<decltype(space)>(space); },
Expand All @@ -26,18 +29,18 @@ class DevGlobalObject : public Zig::GlobalObject {
}

static const JSC::GlobalObjectMethodTable s_globalObjectMethodTable;
static DevGlobalObject* create(JSC::VM& vm, JSC::Structure* structure, const JSC::GlobalObjectMethodTable* methodTable);
static GlobalObject* create(JSC::VM& vm, JSC::Structure* structure, const JSC::GlobalObjectMethodTable* methodTable);

DevServer* m_devServer;
ALWAYS_INLINE bool isProduction() const { return !m_devServer; }

void finishCreation(JSC::VM& vm);

DevGlobalObject(JSC::VM& vm, JSC::Structure* structure, const JSC::GlobalObjectMethodTable* methodTable)
GlobalObject(JSC::VM& vm, JSC::Structure* structure, const JSC::GlobalObjectMethodTable* methodTable)
: Zig::GlobalObject(vm, structure, methodTable) { }
};

// Zig API
extern "C" void KitInitProcessIdentifier();
extern "C" DevGlobalObject* KitCreateDevGlobal(DevServer* owner, void* console);
extern "C" GlobalObject* KitCreateDevGlobal(DevServer* owner, void* console);

}; // namespace Kit
39 changes: 39 additions & 0 deletions src/bake/BakeProduction.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "BakeProduction.h"
#include "BunBuiltinNames.h"
#include "WebCoreJSBuiltins.h"
#include "JavaScriptCore/JSPromise.h"
#include "JavaScriptCore/Exception.h"

namespace Bake {

extern "C" JSC::JSPromise* BakeRenderRoutesForProd(
JSC::JSGlobalObject* global,
BunString outbase,
JSC::JSValue renderStaticCallback,
JSC::JSValue clientEntryUrl,
JSC::JSValue files,
JSC::JSValue patterns,
JSC::JSValue styles)
{
JSC::VM& vm = global->vm();
JSC::JSFunction* cb = JSC::JSFunction::create(vm, global, WebCore::bakeRenderRoutesForProdCodeGenerator(vm), global);
JSC::CallData callData = JSC::getCallData(cb);

JSC::MarkedArgumentBuffer args;
args.append(JSC::jsString(vm, outbase.toWTFString()));
args.append(renderStaticCallback);
args.append(clientEntryUrl);
args.append(files);
args.append(patterns);
args.append(styles);

NakedPtr<JSC::Exception> returnedException = nullptr;
auto result = JSC::call(global, cb, callData, JSC::jsUndefined(), args, returnedException);
if (UNLIKELY(returnedException)) {
// This should be impossible because it returns a promise.
return JSC::JSPromise::rejectedPromise(global, returnedException->value());
}
return JSC::jsCast<JSC::JSPromise*>(result);
}

} // namespace Bake
5 changes: 5 additions & 0 deletions src/bake/BakeProduction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "root.h"
#include "headers-handwritten.h"

namespace Bake {
} // namespace Bake
Loading

0 comments on commit e93c5ad

Please sign in to comment.