ui: s/npm/pnpm
pnpm is alternative to npm which is faster and more robust
clean install-build-deps: >1min -> 10s
incremental install-build-deps: >1min -> 1s
In the same CL upgrade a few packages and fix some issues
this exposed.
Before:
$ rm -rf ui/node_modules/
$ time ./tools/install-build-deps --ui
...snip...
________________________________________________________
Executed in 54.28 secs fish external
usr time 47.01 secs 0.23 millis 47.01 secs
sys time 9.37 secs 1.89 millis 9.37 secs
$ time ./tools/install-build-deps --ui
________________________________________________________
Executed in 55.84 secs fish external
usr time 47.39 secs 0.22 millis 47.39 secs
sys time 12.10 secs 2.63 millis 12.10 secs
After:
$ rm -rf ui/node_modules/
$ time ./tools/install-build-deps --ui
________________________________________________________
Executed in 9.32 secs fish external
usr time 3.09 secs 0.24 millis 3.09 secs
sys time 11.04 secs 3.03 millis 11.04 secs
$ time ./tools/install-build-deps --ui
INFO:root:Running `pnpm install --frozen-lockfile` in /Users/hjd/src/perfetto/ui
Lockfile is up to date, resolution step is skipped
Packages: +1
+
Progress: resolved 1, reused 0, downloaded 1, added 1, done
Done in 365ms
________________________________________________________
Executed in 1.08 secs fish external
usr time 1.06 secs 0.25 millis 1.06 secs
sys time 0.81 secs 2.95 millis 0.81 secs
Change-Id: I7db03ab99132a2f34307051eba301d8ad6d59d2f
diff --git a/tools/install-build-deps b/tools/install-build-deps
index 50cb1ae..adcf3e5 100755
--- a/tools/install-build-deps
+++ b/tools/install-build-deps
@@ -383,7 +383,28 @@
Dependency(
'buildtools/typefaces.tgz',
'https://storage.googleapis.com/perfetto/typefaces-%s.tar.gz' %
- TYPEFACES_SHA256, TYPEFACES_SHA256, 'all', 'all')
+ TYPEFACES_SHA256, TYPEFACES_SHA256, 'all', 'all'),
+
+ Dependency(
+ 'third_party/pnpm/pnpm',
+ 'https://storage.googleapis.com/perfetto/pnpm-linux-arm64-8.6.3',
+ 'ac76e9ab6a770479f93c1a2bf978d72636dbcb02608554378cf30075a78a22ac',
+ 'linux', 'arm64'),
+ Dependency(
+ 'third_party/pnpm/pnpm',
+ 'https://storage.googleapis.com/perfetto/pnpm-linux-x64-8.6.3',
+ '5a58ccd78d44faac138d901976a7a8917c0f2a2f83743cfdd895fcd0bb6aa135',
+ 'linux', 'x64'),
+ Dependency(
+ 'third_party/pnpm/pnpm',
+ 'https://storage.googleapis.com/perfetto/pnpm-macos-arm64-8.6.3',
+ 'f527713d3183e30cfbfd7fd6403ceed730831c53649e50c979961eab3b2cf866',
+ 'darwin', 'arm64'),
+ Dependency(
+ 'third_party/pnpm/pnpm',
+ 'https://storage.googleapis.com/perfetto/pnpm-macos-x64-8.6.3',
+ '6b425f7f0342341e9ee9427a9a2be2c89936c4a04efe6125f7af667eb02b10c1',
+ 'darwin', 'x64'),
]
# Dependencies to build gRPC.
@@ -538,29 +559,35 @@
logging.info('Clearing %s', node_modules)
subprocess.check_call(['git', 'clean', '-qxffd', node_modules],
cwd=ROOT_DIR)
- logging.info("Running `npm ci` in {0}".format(UI_DIR))
- # `npm ci` is like `npm install` but respects package-lock.json.
- subprocess.check_call([os.path.join(TOOLS_DIR, 'npm'), 'ci'], cwd=UI_DIR)
+ logging.info("Running `pnpm install --frozen-lockfile` in {0}".format(UI_DIR))
+
+ # Some node modules have postinstall scripts (already bad) but worse
+ # sometimes they are in the form: "postinstall: 'node ./scripts/foo'"
+ # so here we need to ensure that our hermetic node is available in
+ # PATH.
+ env = os.environ.copy()
+ env['PATH'] = TOOLS_DIR + ':' + env['PATH']
+
+ subprocess.check_call([os.path.join(TOOLS_DIR, 'pnpm'), 'install', '--frozen-lockfile'], cwd=UI_DIR, env=env)
# pbjs has the bad habit of installing extra packages on its first run. Run
# it here, so we avoid fetches while building.
- node_bin = os.path.join(TOOLS_DIR, 'node')
- pbjs = [node_bin, 'node_modules/.bin/pbjs', '/dev/null', '-o', '/dev/null']
- subprocess.call(pbjs, cwd=UI_DIR)
+ pbjs = ['node_modules/.bin/pbjs', '/dev/null', '-o', '/dev/null']
+ subprocess.call(pbjs, cwd=UI_DIR, env=env)
with open(NODE_MODULES_STATUS_FILE, 'w') as f:
- f.write(HashLocalFile(os.path.join(UI_DIR, 'package-lock.json')))
+ f.write(HashLocalFile(os.path.join(UI_DIR, 'pnpm-lock.yaml')))
def CheckNodeModules():
"""Returns True if the modules are up-to-date.
There doesn't seem to be an easy way to check node modules versions. Instead
- just check if package-lock.json changed since the last `npm install` call.
+ just check if pnpm-lock.json changed since the last `pnpm install` call.
"""
if not os.path.exists(NODE_MODULES_STATUS_FILE):
return False
with open(NODE_MODULES_STATUS_FILE, 'r') as f:
actual = f.read()
- expected = HashLocalFile(os.path.join(UI_DIR, 'package-lock.json'))
+ expected = HashLocalFile(os.path.join(UI_DIR, 'pnpm-lock.yaml'))
return expected == actual