Snowpack: Cannot mount folder from聽inside node_modules/.cache folder

Created on 12 Oct 2020  路  6Comments  路  Source: snowpackjs/snowpack

Original Discussion: https://github.com/pikapkg/snowpack/discussions/1267
/cc @bluebrown

This isn't a primary use-case, but if it's easy to support, we should. This needs to be debugged a bit more to see what's going on. See original discussion for more reproduction info:

  "mount": {
    "node_modules/.cache/11ty": "/",
    "src/assets": "/static"
  },
bug

Most helpful comment

btw, in case it's of interest, i would like to mount general things in node_modules (in particular, fonts and images from lightgallery). npx snowpack build ignores these mounts, though npx snowpack dev seems to accept them. (should the behavior be consistent between the two?)

All 6 comments

Hi @FredKSchott,

I found out that node_modules is by default ignored based on this code snippet and below piece of documenation

builds.ts line 382

  // 0. Find all source files.
  for (const [mountedDir, mountEntry] of Object.entries(config.mount)) {
    const allFiles = glob.sync(`**/*`, {
      ignore: [...config.exclude, ...config.testOptions.files],
      cwd: mountedDir,
      absolute: true,
      nodir: true,
      dot: true,
    });
    for (const rawLocOnDisk of allFiles) {
      const fileLoc = path.resolve(rawLocOnDisk); // this is necessary since glob.sync() returns paths with / on windows.  path.resolve() will switch them to the native path separator.
      const finalUrl = getUrlForFileMount({fileLoc, mountKey: mountedDir, mountEntry, config})!;
      const finalDestLoc = path.join(buildDirectoryLoc, finalUrl);
      const outDir = path.dirname(finalDestLoc);
      const buildPipelineFile = new FileBuilder({filepath: fileLoc, outDir, config});
      buildPipelineFiles[fileLoc] = buildPipelineFile;
    }
  }

Docs

exclude | string[]
Exclude any files from scanning, building, etc. Defaults to exclude common test file locations: ['**/node_modules/**/*', '**/__tests__/*', '**/*.@(spec|test).@(js|mjs)']
Useful for excluding tests and other unnecessary files from the final build. Supports glob pattern matching.

Based on this my idea was to use an empty array for the exclude key but it doesnt work

snowpack.json

  "mount": {
    "node_modules/.cache/_11ty": "/",
  },
  "exclude": [],
````


So I check the config.ts file and I found this

config.ts line 34

const ALWAYS_EXCLUDE = ['/node_modules//', '/web_modules//', '/.types//*'];


So if one wanted to solve to very simple, the node_modules could be moved to the default config instead of this "private" exclude array like shown below. However, this would mean the user could accidentally unset this easily. 

```ts

const ALWAYS_EXCLUDE = ['**/web_modules/**/*', '**/.types/**/*']; // move from here 

// default settings
const DEFAULT_CONFIG: Partial<SnowpackConfig> = {
  plugins: [],
  alias: {},
  scripts: {},
  exclude: ['**/node_modules/**/*'], // to here
  installOptions: {},
  devOptions: {
    secure: false,
    hostname: 'localhost',
    port: 8080,
    open: 'default',
    out: 'build',
    output: 'dashboard',
    fallback: 'index.html',
    hmrDelay: 0,
    hmrPort: 12321,
    hmrErrorOverlay: true,
  },
  buildOptions: {
    baseUrl: '/',
    webModulesUrl: '/web_modules',
    clean: false,
    metaDir: '__snowpack__',
    minify: false,
    sourceMaps: false,
    watch: false,
  },
  testOptions: {
    files: ['__tests__/**/*', '**/*.@(spec|test).*'],
  },
  experiments: {
    ssr: false,
  },
};

While Investigating I was thinking of something like and include array as well. Items in this array could overwrite any excluded item which would be more solid for users who don't really know how it works. I imagine something like this.

"mount": {
    "node_modules/.cache/_11ty": "/",
},
"exclude": [
    "something/to/exclude/without/unsetting/node_modules"
],
"include" [
    "path/to/overwrite",
    "node_modules/.cache/.1tty"
]

A third option could be to allow the users to set the always_exlcude array as well in the config which would allow a complete overwrite.

What do you think? I would be happy to tackle either approach or something different and make a pr.

Oh of course! Great catch, that's exactly what's happening.

As a workaround, I wonder if adding this to your config would solve the problem:

// "!" will tell our glob library to do the opposite
"exclude": [
    "!node_modules/.cache/_11ty/**"
],

Hi Fred,

that is actually one thing that I have tried but the result was not what I expected. On second thought it makes sense though.

This will tell now snowpack to ignore everything that's not exactly named "node_modules/.cache/_11ty/**". That's the whole project.

The result is that everything will be ignored, including thenode_modules/.cache directory, since this is still ignored from the ALWAYS_EXCLUDE array,

So in the build is only an env.js and the __snowpack__ folder but nothing else with this setting.

What about "**/node_modules/.cache/_11ty/**/*"? It should work in the same array as ALWAYS_EXCLUDE, so maybe it just needs to be fiddled with a bit?

I think it's not possible to do that with the glob package. See this repl: https://repl.it/talk/share/Glob-Test/57653

I have replicated roughly what is happening with the snowpack config. Below shows the actual code from snowpack.

config.ts line 567

  config.exclude = Array.from(
    new Set([...ALWAYS_EXCLUDE, `${config.devOptions.out}/**/*`, ...config.exclude]),
  );

builds.ts line 382

  for (const [mountedDir, mountEntry] of Object.entries(config.mount)) {
    const allFiles = glob.sync(`**/*`, {
      ignore: [...config.exclude, ...config.testOptions.files],
      cwd: mountedDir,
      absolute: true,
      nodir: true,
      dot: true,
    });

The gist is that this will not return the path to__filename

console.log(glob.sync(`**/*`, {
  ignore: [__filename, "!"+__filename],
  cwd: "./",
  absolute: true,
  nodir: true,
  dot: true,
}));

btw, in case it's of interest, i would like to mount general things in node_modules (in particular, fonts and images from lightgallery). npx snowpack build ignores these mounts, though npx snowpack dev seems to accept them. (should the behavior be consistent between the two?)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

FredKSchott picture FredKSchott  路  6Comments

mfolkeseth picture mfolkeseth  路  5Comments

devongovett picture devongovett  路  4Comments

FredKSchott picture FredKSchott  路  6Comments

gr2m picture gr2m  路  6Comments