UNPKG

4.8 kBJavaScriptView Raw
1'use strict';
2const fs = require('file-system');
3const minimatch = require('minimatch');
4const path = require('path');
5
6const DEFAULT_CONFIG = {
7 'staticPath': [ 'static' ],
8 'watcherGlob': null
9};
10
11module.exports = bundler => {
12 bundler.on('bundled', async(bundle) => {
13
14 // main asset and package dir, depending on version of parcel-bundler
15 let mainAsset =
16 bundler.mainAsset || // parcel < 1.8
17 bundler.mainBundle.entryAsset || // parcel >= 1.8 single entry point
18 bundler.mainBundle.childBundles.values().next().value.entryAsset; // parcel >= 1.8 multiple entry points
19 let pkg;
20 if (typeof mainAsset.getPackage === 'function') { // parcel > 1.8
21 pkg = (await mainAsset.getPackage());
22 } else { // parcel <= 1.8
23 pkg = mainAsset.package;
24 }
25
26 // config
27 let config = Object.assign({}, DEFAULT_CONFIG, pkg.staticFiles);
28 if (pkg.staticPath) { // parcel-plugin-static-files-copy<1.2.5
29 config.staticPath = pkg.staticPath;
30 }
31 if (!Array.isArray(config.staticPath)) { // ensure array
32 config.staticPath = [ config.staticPath ];
33 }
34
35 // poor-man's logger
36 const logLevel = parseInt(bundler.options.logLevel);
37 const pmLog = (level, ...msgs) => {
38 if (logLevel >= level) {
39 console.log(...msgs);
40 }
41 };
42
43 // static paths are usually just a string can be specified as
44 // an object to make them conditional on the output directory
45 // by specifying them in the form
46 // {"outDirPattern":"dist1", "staticPath":"static1"},
47 // {"outDirPattern":"dist2", "staticPath":"static2"}
48 config.staticPath = config.staticPath.map(path => {
49 if (typeof path === 'object') {
50 if (!path.staticPath || !path.outDirPattern) {
51 console.error(`Error: parcel-plugin-static-files-copy: When staticPath is an object, expecting it to have the keys 'staticPath' and 'outDirPattern', but found: ${path}`);
52 return null;
53 }
54
55 if (minimatch(bundler.options.outDir, path.outDirPattern)) {
56 pmLog(3, `outDir matches '${path.outDirPattern}' so copying static files from '${path.staticPath}'`);
57 return path.staticPath;
58 } else {
59 pmLog(3, `outDir does not match '${path.outDirPattern}' so not copying static files from '${path.staticPath}'`);
60 return null;
61 }
62 } else {
63 return path;
64 }
65 }).filter(path => path != null);
66
67 // recursive copy function
68 let numWatches = 0;
69 const copyDir = (staticDir, bundleDir) => {
70 if (fs.existsSync(staticDir)) {
71 const copy = (filepath, relative, filename) => {
72 const dest = filepath.replace(staticDir, bundleDir);
73 if (!filename) {
74 fs.mkdir(filepath, dest);
75 } else {
76 if (fs.existsSync(dest)) {
77 const destStat = fs.statSync(dest);
78 const srcStat = fs.statSync(filepath);
79 if (destStat.mtime <= srcStat.mtime) { // File was modified - let's copy it and inform about overwriting.
80 pmLog(3, `Static file '${filepath}' already exists in '${bundleDir}'. Overwriting.`);
81 fs.copyFile(filepath, dest);
82 }
83 } else {
84 fs.copyFile(filepath, dest);
85 }
86 // watch for changes?
87 if (config.watcherGlob && bundler.watcher && minimatch(filepath, config.watcherGlob)) {
88 numWatches++;
89 bundler.watch(filepath, mainAsset);
90 }
91 }
92 };
93 fs.recurseSync(staticDir, copy);
94 } else {
95 pmLog(2, `Static directory '${staticDir}' does not exist. Skipping.`);
96 }
97 };
98
99 const bundleDir = path.dirname(bundle.name || bundler.mainBundle.childBundles.values().next().value.name);
100 for (let dir of config.staticPath) {
101 copyDir(path.join(pkg.pkgdir, dir), bundleDir);
102 }
103
104 if (config.watcherGlob && bundler.watcher) {
105 pmLog(3, `Watching for changes in ${numWatches} static files.`);
106 }
107
108 });
109};