This PR does two things:

1. I moved `package.json` into the root directory. Why? We are using `npx` from the `Makefile` which is executing usually under the root directory. If we install `node_modules` in `src/js` then these invocations don't see `node_modules` and install an extra copy of the packages. So we want `node_modules` in the root directory. node wants to put `node_modules` in the same directory as `package.json` hence I moved `package.json`. I also updated the build rules so that any recipe that uses `npx` has a dependency on `node_modules/.installed`.
2. We invoke `file_packager.py` from both the Makefile (in two places) and from `build_pkg`. There has been some drift in which options are applied in the two places. I extracted the common options and the task of locating the `file_packager.py` script into `tools/file_packager.sh`. I also shortened the make rules for `distutils.data` and `test.data` and made some minor updates to the dev docs about `file_packager.py`.
MAINT Improvements to node and file_packager invocations. This PR does two things:

1. I moved `package.json` into the root directory. Why? We are using `npx` from the `Makefile` which is executing usually under the root directory. If we install `node_modules` in `src/js` then these invocations don't see `node_modules` and install an extra copy of the packages. So we want `node_modules` in the root directory. node wants to put `node_modules` in the same directory as `package.json` hence I moved `package.json`. I also updated the build rules so that any recipe that uses `npx` has a dependency on `node_modules/.installed`.
2. We invoke `file_packager.py` from both the Makefile (in two places) and from `build_pkg`. There has been some drift in which options are applied in the two places. I extracted the common options and the task of locating the `file_packager.py` script into `tools/file_packager.sh`. I also shortened the make rules for `distutils.data` and `test.data` and made some minor updates to the dev docs about `file_packager.py`.
threading.Timer is not yet supported in Pyodide.

diff --git a/lib/matplotlib/font_manager.py b/lib/matplotlib/font_manager.py
--- a/lib/matplotlib/font_manager.py
+++ b/lib/matplotlib/font_manager.py
@@ -1063,10 +1063,8 @@ class FontManager:
         self.afmlist = []
         self.ttflist = []
 
-        # Delay the warning by 5s.
-        timer = Timer(5, lambda: _log.warning(
-            'Matplotlib is building the font cache; this may take a moment.'))
-        timer.start()
+        _log.warning(
+            'Matplotlib is building the font cache; this may take a moment.')
         try:
             for fontext in ["afm", "ttf"]:
                 for path in [*findSystemFonts(paths, fontext=fontext),
@@ -1079,7 +1077,7 @@ class FontManager:
                         _log.info("Failed to extract font properties from %s: "
                                   "%s", path, exc)
         finally:
-            timer.cancel()
+            pass
 
     def addfont(self, path):
         """
-- 
2.20.1

threading.Timer is not yet supported in Pyodide.

diff --git a/lib/matplotlib/font_manager.py b/lib/matplotlib/font_manager.py
--- a/lib/matplotlib/font_manager.py
+++ b/lib/matplotlib/font_manager.py
@@ -1063,10 +1063,8 @@ class FontManager:
         self.afmlist = []
         self.ttflist = []
 
-        # Delay the warning by 5s.
-        timer = Timer(5, lambda: _log.warning(
-            'Matplotlib is building the font cache; this may take a moment.'))
-        timer.start()
+        _log.warning(
+            'Matplotlib is building the font cache; this may take a moment.')
         try:
             for fontext in ["afm", "ttf"]:
                 for path in [*findSystemFonts(paths, fontext=fontext),
@@ -1079,7 +1077,7 @@ class FontManager:
                         _log.info("Failed to extract font properties from %s: "
                                   "%s", path, exc)
         finally:
-            timer.cancel()
+            pass
 
     def addfont(self, path):
         """
-- 
2.20.1
