在Nix Shell(Flake)中用Parcel遇"Got unexpected undefined"错误
问题场景
使用Flake搭建Nix Shell环境构建Parcel项目,配置如下flake.nix:
{ description = "My Project"; inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; flake-utils.url = "github:numtide/flake-utils"; }; outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachSystem [ flake-utils.lib.system.x86_64-linux ] (system: let pkgs = import nixpkgs { inherit system; }; in { devShells.default = pkgs.mkShell { buildInputs = with pkgs; [ nodePackages.parcel ]; }; } ); }
项目包含src/index.html:
<!DOCTYPE html> <div id="root"></div>
进入Nix Shell后,parcel --help可正常运行,但执行parcel src/index.html、parcel serve、parcel build等命令时触发以下错误:
❯ parcel src/index.html Error: Got unexpected undefined at nullthrows (/nix/store/qgwakdviwvk2sjv0bqk2w0bjvi4aqx3q-parcel-2.12.0/lib/node_modules/parcel/node_modules/nullthrows/nullthrows.js:7:15) at Object.<anonymous> (/nix/store/qgwakdviwvk2sjv0bqk2w0bjvi4aqx3q-parcel-2.12.0/lib/node_modules/parcel/node_modules/@parcel/node-resolver-core/lib/builtins.js:66:38) at Module._compile (node:internal/modules/cjs/loader:1469:14) at Module._extensions..js (node:internal/modules/cjs/loader:1548:10) at Module.load (node:internal/modules/cjs/loader:1288:32) at Module._load (node:internal/modules/cjs/loader:1104:12) at Module.require (node:internal/modules/cjs/loader:1311:19) at require (node:internal/modules/helpers:179:18) at Object.<anonymous> (/nix/store/qgwakdviwvk2sjv0bqk2w0bjvi4aqx3q-parcel-2.12.0/lib/node_modules/parcel/node_modules/@parcel/node-resolver-core/lib/Wrapper.js:21:41) at Module._compile (node:internal/modules/cjs/loader:1469:14) { framesToPop: 1 }
排查与解决方向
替换
nodePackages.parcel为pkgs.parcel
nixpkgs中nodePackages.parcel是通过npm2nix自动打包的版本,可能存在路径解析或依赖缺失问题。直接使用官方维护的pkgs.parcel包,修改flake.nix的buildInputs:buildInputs = with pkgs; [ parcel ];切换Parcel版本
当前使用的Parcel 2.12.0在Nix环境下可能存在兼容性问题,尝试降级到稳定版本(如2.11.0),通过overrideAttrs覆盖版本:let pkgs = import nixpkgs { inherit system; }; parcel = pkgs.parcel.overrideAttrs (old: { version = "2.11.0"; src = pkgs.fetchFromGitHub { owner = "parcel-bundler"; repo = "parcel"; rev = "v2.11.0"; sha256 = "sha256-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; }; }); in { devShells.default = pkgs.mkShell { buildInputs = [ parcel ]; }; }可通过
nix-prefetch-url --unpack https://github.com/parcel-bundler/parcel/archive/v2.11.0.tar.gz获取对应的sha256值。补充Node.js环境变量与系统依赖
Nix隔离环境下可能缺少Parcel所需的环境变量或系统库,尝试添加nodejs依赖并设置NODE_PATH:devShells.default = pkgs.mkShell { buildInputs = with pkgs; [ parcel nodejs ]; shellHook = '' export NODE_PATH="${pkgs.nodePackages.node_modules}/lib/node_modules" ''; };使用本地包管理器安装Parcel
避免全局打包的问题,改用pnpm/yarn在项目本地安装Parcel:- 修改
flake.nix的buildInputs为[ nodejs pnpm ] - 进入Nix Shell后执行:
pnpm init -y pnpm add -D parcel pnpm exec parcel src/index.html
- 修改
检查Nixpkgs包的构建补丁
查看Nixpkgs中Parcel包的构建脚本,确认是否有未适配的问题:nix show-derivation nixpkgs#parcel或查看本地nixpkgs仓库中Parcel的
default.nix文件,检查是否有相关补丁缺失。
内容的提问来源于stack exchange,提问作者The Oddler

