Git Product home page Git Product logo

webpack-virtual-modules's Introduction

Webpack Virtual Modules

npm version npm downloads License

Webpack Virtual Modules is a plugin that allows for dynamical generation of in-memory virtual modules for JavaScript builds created with webpack. When virtual module is created all the parent virtual dirs that lead to the module filename are created too. This plugin supports watch mode meaning any write to a virtual module is seen by webpack as if a real file stored on disk has changed.

Installation

Use NPM or Yarn to install Webpack Virtual Modules as a development dependency:

# with NPM
npm install webpack-virtual-modules --save-dev

# with Yarn
yarn add webpack-virtual-modules --dev

Usage

You can use Webpack Virtual Modules with webpack 5, 4 and 3. The examples below show the usage with webpack 5 or 4. If you want to use our plugin with webpack 3, check out a dedicated doc:

Generating static virtual modules

Require the plugin in the webpack configuration file, then create and add virtual modules in the plugins array in the webpack configuration object:

var VirtualModulesPlugin = require('webpack-virtual-modules');

var virtualModules = new VirtualModulesPlugin({
  'node_modules/module-foo.js': 'module.exports = { foo: "foo" };',
  'node_modules/module-bar.js': 'module.exports = { bar: "bar" };'
});

module.exports = {
  // ...
  plugins: [
    virtualModules
  ]
};

You can now import your virtual modules anywhere in the application and use them:

var moduleFoo = require('module-foo');
// You can now use moduleFoo
console.log(moduleFoo.foo);

Generating dynamic virtual modules

You can generate virtual modules dynamically with Webpack Virtual Modules.

Here's an example of dynamic generation of a module. All you need to do is create new virtual modules using the plugin and add them to the plugins array. After that, you need to add a webpack hook. For using hooks, consult webpack compiler hook documentation.

var webpack = require('webpack');
var VirtualModulesPlugin = require('webpack-virtual-modules');

// Create an empty set of virtual modules
const virtualModules = new VirtualModulesPlugin();

var compiler = webpack({
  // ...
  plugins: [
    virtualModules
  ]
});

compiler.hooks.compilation.tap('MyPlugin', function(compilation) {
  virtualModules.writeModule('node_modules/module-foo.js', '');
});

compiler.watch();

In other module or a Webpack plugin, you can write to the module module-foo whatever you need. After this write, webpack will "see" that module-foo.js has changed and will restart compilation.

virtualModules.writeModule(
  'node_modules/module-foo.js',
  'module.exports = { foo: "foo" };'
);

More Examples

API Reference

Inspiration

This project is inspired by virtual-module-webpack-plugin.

License

Copyright © 2017 SysGears INC. This source code is licensed under the MIT license.

webpack-virtual-modules's People

Contributors

86 avatar adamburgess avatar adrianbannister avatar andsviat avatar borayuksel1903 avatar dependabot[bot] avatar fyodorovandrei avatar greenkeeper[bot] avatar larixer avatar lemonmade avatar miserylee avatar non25 avatar opl- avatar samcooke98 avatar thierrymichel avatar timse avatar vovacodes avatar zn4rk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webpack-virtual-modules's Issues

[Question] - Is it possible generate new virtual modules based on file-system changes?

Hi.

I'm trying to create (for the first time) a webpack plugin that (in a few words) creates a virtual modules based on the application files. I am able to correctly write a virtual module thanks to the examples explained in this repo, but I'm wondering if it would be possible to re-generate the virtual modules contents based on the changes on the "physical" files.

[]s,

Impossible base case (TypeScript?)

Describe the bug

I don't know why but I seem unable to make the basic use-case work. I can find no way to have a virtual module declared with webpack using this plugin. I must miss a detail.

It is perhaps due to ts-loader or something, I really have no idea.

To Reproduce

https://github.com/eddow/eddow-bug-expo

Screenshots

ERROR in C:\dev\github\eddow-bug-expo\test\test1.ts
./test1.ts
[tsl] ERROR in C:\dev\github\eddow-bug-expo\test\test1.ts(1,22)
      TS2307: Cannot find module 'module-foo' or its corresponding type declarations.

ERROR in C:\dev\github\eddow-bug-expo\test\test2.ts
./test2.ts
[tsl] ERROR in C:\dev\github\eddow-bug-expo\test\test2.ts(1,22)
      TS2307: Cannot find module './module-foo' or its corresponding type declarations.

Environment if relevant (please complete the following information):

  • Node version v14.14.0
  • Webpack version 5.1.3

[Bug] webpack 5 updated files do not trigger rebuilds

  • I'd be willing to submit the fix

Describe the bug

Here is a repo demostrating the issue: https://github.com/jquense/webpack-pitch-repro/tree/virtual-modules

It's a bit convoluted, but bear with me it mirrors a real use case. Basically a loader will produce a virtual file that is. If during a rebuild the file is updated it's emitted but the emitted file will not be rebuilt by webpack. The same is not true if you write out a real file.

To Reproduce

https://github.com/jquense/webpack-pitch-repro/tree/virtual-modules

run yarn start, open the page, see the text. Open index.js change the string in evil and notice web pack rebuilds but the string doesn't update.

Environment if relevant (please complete the following information):

  • Webpack version 5

Compatibility with AngularCompilerPlugin

Is this plugin compatible with AngularCompilerPlugin? I keep getting the following error:

TypeError: Cannot read property 'data' of undefined
    at setData (/Users/ben/projects/sopher.io/sites/webapp/node_modules/webpack-virtual-modules/index.js:79:15)
    at VirtualFileSystemDecorator.compiler.inputFileSystem._writeVirtualFile (/Users/ben/projects/sopher.io/sites/webapp/node_modules/webpack-virtual-modules/index.js:108:9)
    at VirtualModulesPlugin.writeModule (/Users/ben/projects/sopher.io/sites/webapp/node_modules/webpack-virtual-modules/index.js:59:34)
    at /Users/ben/projects/sopher.io/sites/webapp/node_modules/webpack-virtual-modules/index.js:155:14
    at Array.forEach (<anonymous>)
    at afterResolversHook (/Users/ben/projects/sopher.io/sites/webapp/node_modules/webpack-virtual-modules/index.js:154:40)
    at SyncHook.eval [as call] (eval at create (/Users/ben/projects/sopher.io/sites/webapp/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:5:1)
    at SyncHook.lazyCompileHook (/Users/ben/projects/sopher.io/sites/webapp/node_modules/tapable/lib/Hook.js:154:20)
    at WebpackOptionsApply.process (/Users/ben/projects/sopher.io/sites/webapp/node_modules/webpack/lib/WebpackOptionsApply.js:541:33)
    at webpack (/Users/ben/projects/sopher.io/sites/webapp/node_modules/webpack/lib/webpack.js:57:48)
    at processOptions (/Users/ben/projects/sopher.io/sites/webapp/node_modules/webpack-cli/bin/cli.js:272:16)
    at /Users/ben/projects/sopher.io/sites/webapp/node_modules/webpack-cli/bin/cli.js:364:3
    at Object.parse (/Users/ben/projects/sopher.io/sites/webapp/node_modules/webpack-cli/node_modules/yargs/yargs.js:567:18)
    at /Users/ben/projects/sopher.io/sites/webapp/node_modules/webpack-cli/bin/cli.js:49:8
    at Object.<anonymous> (/Users/ben/projects/sopher.io/sites/webapp/node_modules/webpack-cli/bin/cli.js:366:3)
    at Module._compile (internal/modules/cjs/loader.js:1123:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1143:10)
    at Module.load (internal/modules/cjs/loader.js:972:32)
    at Function.Module._load (internal/modules/cjs/loader.js:872:14)
    at Module.require (internal/modules/cjs/loader.js:1012:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at Object.<anonymous> (/Users/ben/projects/sopher.io/sites/webapp/node_modules/webpack/bin/webpack.js:156:2)
    at Module._compile (internal/modules/cjs/loader.js:1123:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1143:10)
    at Module.load (internal/modules/cjs/loader.js:972:32)
    at Function.Module._load (internal/modules/cjs/loader.js:872:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47

This is an excerpt of the plugins in the webpack.config.js:

 plugins: [
    new VirtualModulesPlugin({
      'node_modules/module-foo.js': 'module.exports = { foo: "foo" };'
    }),
    new AngularCompilerPlugin({
      tsConfigPath: path.resolve(TSCONFIG),
      sourceMap: SOURCE_MAPS
    })
]

CSS example

Is there any chance you have a basic example of how I can use this to inject some CSS into my bundle?

I have it almost working, but my build never completes. Im useing webpack loader utils to generate a path like this

const cssPath = loaderUtils.interpolateName(
    this,
    '[path][name].[hash:base64:7].css',
    {
      content: 'p { text-align: center }'
    }
  );

But when I log the cssPath, it looks like it just builds onto itself

/example-project/src/styles.MINrvtm.css
/example-project/src/styles.MINrvtm.MINrvtm.css
/example-project/src/styles.MINrvtm.MINrvtm.MINrvtm.css
/example-project/src/styles.MINrvtm.MINrvtm.MINrvtm.MINrvtm.css
/example-project/src/styles.MINrvtm.MINrvtm.MINrvtm.MINrvtm.MINrvtm.css

If the dir of the path not exist, this plugin will not work.

For example:

/root
   node_module
   src
   test
      webpack.config.js
   package.json

run the webpack in test, and add a virtual path: node_modules/a.json. The webpack context is test, not root, so the webpack resolver will search test/node_modules first. however it does not exists. Then webpack think a.json is not in the directory test/node_modules, and will be unable to resolve it.

how to require the virtual module in plugin

In my plugin:

class MyPlugin {
    public apply(compiler: Compiler) {
        const virtualModules = new VirtualModulesPlugin({
            'path/to/module': JSON.stringify(someObj);
        })
        virtualModules.apply(compiler);
        compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
            require('path/to/module') // failed.
            compilation.hooks.normalModuleLoader.tap(PLUGIN_NAME, () => {
                require('path/to/module') // still failed.
            })
        })
    }
}

[Feature] GetModule/ReadModule API

  • I'd be willing to implement this feature

Describe the user story

As a Webpack Consumer, I would like to be able to query the VirtualModulesPlugin, so that I can inspect or modify the source for my Virtual Module at a later time if necessary.

Describe the solution you'd like

const virtualModules = new VirtualModulesPlugin();

var compiler = webpack({
  // ...
  plugins: [
    virtualModules
  ]
});

virtualModules.writeModule(
  'node_modules/module-foo.js',
  'module.exports = { foo: "foo" };'
);

const myMod = virtualModules.readModule('node_modules/module-foo.js'); // module.exports = { foo: "foo" };

// If the goal is to update it, you can just call `writeModule` again:
virtualModules.writeModule(
  'node_modules/module-foo.js',
  myMod.replace(/"foo"/, '"bar"')
);

Describe the drawbacks of your solution

Pure addition. Should not have any impact to existing functionality.

Describe alternatives you've considered

This disgusting, fragile, private-api-harassing behemoth:

const virt = new VirtualModulesPlugin();

virt.writeModule(
    'node_modules/module-foo.js',
    'module.exports = { foo: "foo" };'
);

// ...

const { _staticModules: mods } = virt;

const key = Object.keys(mods).find(
    f => f.indexOf('node_modules/module-foo.js') > -1
);

mods[key] = mods[key].replace(/"foo"/, '"bar"');

[Bug]

  • I'd be willing to submit the fix

Describe the bug

Generating dynamic virtual modules not update when writeModule.

To Reproduce
image

Screenshots

image

Environment if relevant (please complete the following information):

├─ [email protected]
├─ [email protected]
├─ [email protected]
├─ [email protected]

  • OS: [e.g. OSX, Linux, Windows, ...] Mac OSX
  • Node version [e.g. 8.15.0, 10.15.1, ...] v16.15.0
  • Webpack version [e.g. 4.26.1, ...] 5.75.0

Additional context

Add any other context about the problem here.

[Bug] Question: Trigger webpack rebuild

This is just a question:

Is there a way to trigger Webpack to trigger a recompile on file changes? I've got a JavaScript module that builds out CSS. That's what I'm loading as a virtual module.

I've got mine building fine, but when I make changes to my file they are not showing up in my dev work. I have to restart webpack.
I've even tried using the webpack-watch-files-plugin to watch for changes and it looks like that is running fine, but my CSS changes do not get incorporated.

Additional context

The CSS module is being loaded the same way as in this thread: #70

[Feature] Webpack 5 `cache` support

  • I'd be willing to implement this feature

Describe the user story

I am currently using this module as part of @marko/webpack. The loader for this module adds virtual modules while compiling the Marko templates.

Problem is that with the new filesystem cache in webpack 5 since those compilations are cached this module does not properly represent the virtual file system anymore.

Describe the solution you'd like

I think it'd be nice if this module would store any virtual files in the compilation in the webpack cache compilation.cache.store and retrieve them when the compilation initializes.

Describe the drawbacks of your solution

The cache api's are async and so it may slightly complicate the code.

virtual-module-webpack-plugin

👋 I was randomly reading twitter and saw a tweet that gave a shout out to this project - https://twitter.com/Rich_Harris/status/1319022088989147138 - and then I noticed your readme linked to my project that experimentally did something similar. 😊 Thanks for that. I haven't tested Webpack 5, but it probably breaks my plugin. I'm thinking of updating my repository's readme to link to here and suggest that people use this project if they stumble on mine. I just wanted to give you a heads up. Let me know if you have any concerns. Otherwise, go ahead and close this issue and I'll push the update to my readme.
Cheers,
Rob

[Feature] Custom URI scheme

  • I'd be willing to implement this feature

Describe the user story

I'd like to namespace all my virtual modules under a separate URI scheme. To make it clear that they are virtual modules and not just regular packages.

Describe the solution you'd like

Something like virtual:myModule.
Used like import foo from 'virtual:myModule'

Describe the drawbacks of your solution

I guess the biggest drawback is extra complexity in the plugin source code.

Describe alternatives you've considered

I'm doing virtual-myModule for now. But that is still something a regular module could be called. So it's not exactly as clear as I'd want it to be.

Additional context

Heavily inspired by Vite's conventions: https://vitejs.dev/guide/api-plugin#virtual-modules-convention

[Bug] Old version of file shown on initial load, one save fixes it

Getting a strange bug where Webpack serves a stale version of a module file that I write to throughout the initial build.

Sorry for not providing example code here, just wondering if you may have an idea how this even happens as a starting point so I can debug it a bit more on my own...

I have a monorepo with a few packages, Webpack runs fine, I to create a fake module module/style.css which works - except on the first load it serves a version of the file from earlier in the build process. It seems like it only gets the styles from within the app, but not within another package that also writes to the same virtual module.

But, if I log out during build, it's definitely writing out the correct final file before the end of the first build. It just seems to not notify the app that file uploaded. It's all in one big chunk during dev mode.

If I save any file in the app, it will work from then on just fine. It's just on initial load for whatever reason.

[Bug] Webpack 3 and 5 rebuild all virtual modules on any change

  • I'd be willing to submit the fix

Describe the bug

Webpack 3 and 5 reloads and rebuilds all virtual modules on any change.

To Reproduce

Test is already in master branch. Disabled for webpack 3 and 5.

Additional context

I'm not sure what to do for now, but I thought a robust test for that problem could be useful as a start. See #78.

[Question] Next.js compatibility

Hi!
Just wanted to ask if there are any known cases of this plugin being successfully used with next.js? 😊

Asking because I've seen cases where next.js might encounter problems when used with webpack plugins.

[Bug] Plugin causes console noise when used alongside debug.js

  • I'd be willing to submit the fix

Describe the bug

When using the DEBUG environment variable to control what log messages we would like to see while using the debug package we are getting flooded by console.log messages from this plugin.

To Reproduce

Run a webpack build with this plugin loaded and set the DEBUG environment variable to anything. It will spit out tons of console.log messages.

Additional context

The offending code is here:

if (process.env.DEBUG)
// eslint-disable-next-line no-console
console.log(this._compiler.name, 'Write virtual module:', modulePath, contents);

Might I suggest to changing the environment variable being checked to something like WVM_DEBUG. I'd happily create a PR if you are okay with this.

[Bug] Multiple config and broken invalidation right from the start

Describe the bug
When running in watch mode with an array of webpack configs the plugin causes compilation invalidation right from the start.
invalid hook receives null when a string with the fileName is expected.

This behaviour can break other plugins which expect a string for invalid hook.

To Reproduce
https://github.com/plesiecki/multiconfig-virtual-modules-repro

Environment if relevant (please complete the following information):

  • Node version 18.18.2
  • Webpack version 5.89.0

Additional context

  • Subsequent calls of the invalid hook receive a string (e.g. after saving the source file index.js).
  • All good in case of single webpack config.

Ability to reset files

I'm using this to overlay my files on a filesystem. I'd like to be able to "reset" a file to its original contents. I can do this with writeModule and readFileSync right now, but it would be nice if writeModules('filename', contents) had a resetModule('filename') to undo the machinations for subsequent runs.

[Feature] Support removeModule API

  • I'd be willing to implement this feature

Describe the user story

We will remove virtual modules in some cases.

Describe the solution you'd like

In watch mode, we can remove virtual modules to release memory.

Describe the drawbacks of your solution

New API.

Describe alternatives you've considered

Additional context

[Bug] Creating virtual files on the fly causes infinite watched rebuilds

  • I'd be willing to submit the fix

Describe the bug

I don't necessarily know all the virtual files I want to create up front, so I've been creating them on a beforeResolve hook if they match a pattern. This worked fine up to and including 0.3.1. Since 0.3.2 this causes infinite rebuilds (which I guess makes sense given I'm creating files mid way through a build).

I'm not sure if this was ever a supported scenario so this may well be a feature request, but it was working until very recently

Is there a way to keep this working? Or alternatively a better approach?

To Reproduce

Add the following plugin to your webpack config and import testfile.virtual.js from a file in the build.
Start a watched build.

class ReproPlugin {
    apply(compiler) {
        const virtualModules = new VirtualModulesPlugin();
        virtualModules.apply(compiler);

        compiler.hooks.compilation.tap(this.constructor.name, (compilation, { normalModuleFactory }) => {
            normalModuleFactory.hooks.beforeResolve.tap(this.constructor.name, (result) => {
                if (/\.virtual\.js$/i.test(result.request)) {
                    virtualModules.writeModule(
                        path.resolve(result.context, result.request),
                        '// test content');
                }
                // uncomment if webpack < 5
                // return result;
            });
        });
    }
}

Prior to 0.3.2 this would build happily and wait for new changes. In 0.3.2 it builds repeatedly.

Screenshots

If applicable, add screenshots to help explain your problem.

Environment if relevant (please complete the following information):

  • OS: Windows 10
  • Node version: 12.16.3
  • Webpack version: 5.3.2
  • webpack-virtual-modules: 0.3.2

Additional context

The virtual files I'm creating don't exist in any form on disk so I wasn't able get a custom loader to work instead.

[Bug] Local version of webpack-virtual-modules in next-with-linaria

Hi! Apologies for a bit unconventional bug report.

I came to this repository when trying to debug the following issue in next-with-linaria project:
dlehmhus/next-with-linaria#19

The author of next-with-linaria @dlehmhus decided to include a patched version of webpack-virtual-modules into their repository. The patch is the following:

https://github.com/dlehmhus/next-with-linaria/blob/62f4603fa8ce8d723749152615ec6c684b3cd45a/src/plugins/webpack-virtual-modules/index.ts#L120

I do not fully understand how webpack-virtual-modules work and cannot tell if this patch is legitimate. If it is legitimate, would it be possible to add an optional parameter to VirtualModulesPlugin constructor or writeModule member function to switch between "throw new Error(Plugin has not been initialized);" and next-with-linaria patch behaviours. So, the author of next-with-linaria can just add webpack-virtual-modules to the packages instead of including the whole source code?

Also, I would be grateful if someone more knowledgeable could take a look at the next-with-linaria issue 19 mentioned above. It is quite puzzling to me why removing the following code in webpack-virtual-modules fixes that issue (at least from the user interface point of view):

setData(getReadDirBackend(finalInputFileSystem), dir, createWebpackData(files));

[Bug] Infinite loop on the webpack 5 example

  • I'd be willing to submit the fix

Describe the bug

When running the webpack 5 example, there is an endless loop with webpack compiling the same files again and again.

To Reproduce

Just run the webpack 5 example.

Screenshots
image

Environment if relevant (please complete the following information):

  • OS: OSX Big Sur
  • Node version 14
  • Mochapack version NA
  • Webpack version 5

[Bug] Virtual modules are rebuilt on any change

Hi dear devs!

  • I'd be willing to submit the fix

Describe the bug

Virtual modules are rebuilt on any change

To Reproduce

https://github.com/non25/webpack-virtual-modules-rebuild-repro

Environment if relevant (please complete the following information):

  • Arch Linux latest
  • Node version v14.9.0
  • Webpack version v4.44.1

Additional context

Originally this was started in hopes to fix svelte-loader (which adapted this plugin) from reloading virtually generated css which on some setups could waste up to 40s of time on any change.

This issue and info could be relevant:
webpack/webpack#5824

Any insight is appreciated.

Resolve dependency issue

Hello, I installed React Storybook to my project but not sure why there's always dependency error from my yarn when I'm trying to run my webpack dev server:

error "@storybook/react#@storybook/core#webpack-virtual-modules#debug" is wrong version: expected "^3.0.0", got "2.6.9"

I don't see any dependency in the yarn.lock:

webpack-virtual-modules@^0.2.0:
  version "0.2.1"
  resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.2.1.tgz#8ab73d4df0fd37ed27bb8d823bc60ea7266c8bf7"
  integrity sha512-0PWBlxyt4uGDofooIEanWhhyBOHdd+lr7QpYNDLC7/yc5lqJT8zlc04MTIBnKj+c2BlQNNuwE5er/Tg4wowHzA==

It worked when I preserve version 3.0.0 but and my yarn always strips away debug 3.0.0 each time after running yarn install.

-debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5:
+debug@^3.1.0, debug@^3.1.1, debug@^3.2.5:
   version "3.2.6"
   resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
   integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==

Any idea how to resolve this?

[Bug] Using React/JSX with `webpack-virtual-modules` gives error even when `@babel/preset-react` is used

  • I'd be willing to submit the fix

Describe the bug

I am trying to bundle some React code which is provided as strings, not as actual files. I think webpack-virtual-modules is what I need, but tell me if this use case is wrong. It seems to work fine if I'm not using jsx, but jsx causes these errors.

Any examples of using webpack-virtual-modules with React?

Error:

../../../../index.jsx 39 bytes [built] [code generated] [1 error]

ERROR in ../../../../index.jsx
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /index.jsx: Support for the experimental syntax 'jsx' isn't currently enabled (5:19):

  3 |   import App from "./components/App";
  4 |   
> 5 |   ReactDOM.render(<App />, document.getElementById("app"))
    |                   ^
  6 |   

Add @babel/preset-react (https://github.com/babel/babel/tree/main/packages/babel-preset-react) to the 'presets' section of your Babel config to enable transformation.
If you want to leave it as-is, add @babel/plugin-syntax-jsx (https://github.com/babel/babel/tree/main/packages/babel-plugin-syntax-jsx) to the 'plugins' section to enable parsing.

To Reproduce

I have the following webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin")
const VirtualModulesPlugin = require('webpack-virtual-modules');

const virtualModules = new VirtualModulesPlugin({
  '/index.html': `<!DOCTYPE html>
  <html lang="en">
  
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>My React App</title>
  </head>
  
  <body>
      <div id="app"></div>
  </body>
  
  </html>`,
  '/index.jsx': `import React from "react";
  import ReactDOM from "react-dom";
  import App from "./components/App";
  
  ReactDOM.render(<App />, document.getElementById("app"))
  `,
  '/components/App.jsx': `import React from "react";

  const App = () => {
      return <>react component</>
  }
  
  export default App`
});

module.exports = {
  entry: path.resolve('/index.jsx'),
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: ['babel-loader'],
      }
    ]
  },
  plugins: [new HtmlWebpackPlugin({ template: "/index.html" }), virtualModules],
  resolve: {
    extensions: ['*', '.js', '.jsx'],
  },
  devServer: {
    static: path.resolve(__dirname, './dist'),
  },
};

And my .bablerc:

{
    "presets": [
        "@babel/preset-env",
        "@babel/preset-react"
    ]
}

Trying to run webpack --mode production on this gives the error described above.

Screenshots

If applicable, add screenshots to help explain your problem.

Environment if relevant (please complete the following information):

  • OS: [e.g. OSX, Linux, Windows, ...]
  • Node version [e.g. 8.15.0, 10.15.1, ...]
  • Mochapack version [e.g. 1.1.3, ...]
  • Webpack version [e.g. 4.26.1, ...]

Additional context

Add any other context about the problem here.

Module Not Found When Using index.js

Hello again, another small issue found.

Expected

Trying to add a Virtual Module located (virtually) where the endpoint is ./assets/number-one/index.js. Other JS files in the same directory should be able to access this file using ./assets/number-one (where the index.js is omitted). For example in the entry file, the /asset/number-one/index.js can be required like the following.

require('./asset/number-one')

and another random file /something/random.js could require /asset/number-one/index.js like the following.

require('../asset/number-one')

Actual

Having a problem trying to resolve modules that is using index.js as the virtual endpoint. The following error shows on terminal.

$ npx webpack --config webpack.config.js
Hash: 4b46b354a8279f7e6198
Version: webpack 4.39.3
Time: 81ms
Built at: 09/09/2019 3:33:54 PM
          Asset      Size  Chunks             Chunk Names
index.bundle.js  3.93 KiB   index  [emitted]  index
Entrypoint index = index.bundle.js
[./entry.js] 30 bytes {index} [built]

ERROR in ./entry.js
Module not found: Error: Can't resolve './assets/number-one' in '/server/node/virtual-modules-test'
 @ ./entry.js 1:0-30

Recreate

The following is the code I wrote.

//# FILE: webpack.config.js
const path = require('path');
const VirtualModulesPlugin = require('webpack-virtual-modules');

module.exports = {
  mode: 'development',
  entry: {
    index: './entry.js'
  },
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'public')
  },
  plugins: [
    new VirtualModulesPlugin({
      './entry.js': 'require(\'./assets/number-one\')',
      './assets/number-one/index.js': 'module.exports = 1'
    })
  ]
};

Known Work Arounds

1. Not using index.js

I could refactor the config to use ./assets/number-one.js like the following snippet.

...
plugins: [
    new VirtualModulesPlugin({
      './entry.js': 'require(\'./assets/number-one\')',
      './assets/number-one.js': 'module.exports = 1'
    })
  ]
...

but trying to convert an actual module (outside of the public directory) to a virtual module could be cumbersome. Consider the following series of files that would not work.

...
plugins: [
    new VirtualModulesPlugin({
      './entry.js': 'require(\'./assets/number-one\')',
      './assets/number-one/index.js': 'require(\'./number-2\')'
      './assets/number-one/number2.js': 'module.exports = 2'
    })
  ]
...
2. Not using VirtualModulesPlugin for this purpose.

In the normal webpack way, index.js is resolved (but for my purpose I would need to do a symlink to path an arbitrary directory into the public path build). I could also consider using alias instead as well (but lose the relative pathing). Maybe some advice instead?

[Bug] ModuleNotFoundError happened ,when I compile two project in the same progress

  • I'd be willing to submit the fix
    Sorry, it's too hard to submit the fix.

Describe the bug

Hello, sorry to report this issue, but I really can't solve this problem, thanks to help!

ModuleNotFoundError happened, when I compile two projects in the same progress.

To Reproduce
Just use simple code to reproduce.
// index.js

const foo = require("module-foo");
console.log(foo);

// webpack.config.js

var VirtualModulesPlugin = require("webpack-virtual-modules");

var virtualModules = new VirtualModulesPlugin({
  "node_modules/module-foo.js": 'module.exports = { foo: "foo" };',
});

/**
 * @type {()=>import('webpack').Configuration}
 */
const config = () => ({
  entry: "./index.js",
  output: {
    path: require("path").resolve(__dirname, "./dist"),
  },

  plugins: [virtualModules],
});

/**
 * @type {()=>import('webpack').Configuration}
 */
const another = () => ({
  entry: "./index.js",
  output: {
    path: require("path").resolve(__dirname, "./dist2"),
  },
  plugins: [virtualModules],
});

module.exports = [another, config];

Environment if relevant (please complete the following information):

System:
OS: macOS 11.7
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 1.31 GB / 32.00 GB
Binaries:
Node: 17.9.1 - ~/Library/Caches/fnm_multishells/12569_1672806001367/bin/node
Yarn: 1.22.19 - ~/Library/Caches/fnm_multishells/57324_1672722484275/bin/yarn
npm: 8.11.0 - ~/Library/Caches/fnm_multishells/12569_1672806001367/bin/npm
Packages:
webpack: ^5.75.0 => 5.75.0
webpack-cli: ^5.0.1 => 5.0.1
webpack-virtual-modules: ^0.5.0 => 0.5.0

[Bug] Stale virtual module contents upon ".writeModule"

  • I'd be willing to submit the fix

Describe the bug

I have a file system watcher (gatsby-page-utils). I derive a JSON from the file changes (addition/removal) of a given directory. I then use your plugin to write the contents of that JSON as a virtual module for my build.

The issue is that when a file is added/removed, although .writeModule is called with the right JSON, the value of the virtual module remains stale. Actually, I believe it remains the same as when the build was done. Nothing changes the value: working with files, changing the build's entrypoint.

To Reproduce

  1. Checkout this pull request.
  2. yarn install && yarn build
  3. Run yarn reproduce. This will open a local dev server.
  4. Open the DevTools, switch to "Console".
  5. See the virtual module's contents (entry.js) in the console.
  6. Try adding/removing *.js files in the examples/virtual-issue directory.
  7. See the console outputting the same JSON.

You can observe the value of the serializedPages in the FileRouterPlugin plugin to see that .writeModule() call receives updated value.

Environment if relevant (please complete the following information):

  • OS: MacOS Catalina 10.15.5
  • Node version: v12.18.0
  • Webpack version: 5.15.0

Additional context

I'm building a plugin that represents a given directory as a JSON, watches for changes, and exposes that JSON to your bundle. I'd love to use your plugin underneath to provide that JSON as a virtual module. Thank you for creating this plugin!

Files disappear and cannot be read by inputFileSystem

I am writing a CSS-in-JS CSS extraction loader. On the first webpack build, this appears to work fine. I use Virtual.writeModule('file.js.extracted.css', contents) and it is then picked up by the first CSS loader.

However, after the first compilation, this.fs.readFileSync() does not return contents.
I use that call to check if the file should be updated. But it just errors.
Then I call Virtual.writeModule('file.js.extracted.css', contents) which seems to work okay.
Stepping through, I see that the virtual files are there on the private property. But then the first CSS loader cannot read the file and emits an ENOENT: no such file or directory. This error comes from webpack's graceful-fs.

Is it possible to get this working in watch mode after the first 60 seconds since the start of the initial build?

What are some real usecases of this plugin?

As title. I use webpack for frontend development, specifically, React. Is this plugin can do things like HMR and replace some of those existing plugins? If not, what are the real usecases this plugin will be helpful? I'm a learner and I want to know it. Thank you.

Problem with virtual files in the main public folder

Thanks for writing this package. Your a real time saver :) . I tried everything you documented and all works great! I even tried making a virtual entry point and that works too. I'm only really having one problem, so I hope you can help me with this or clarify.

Expected

Trying to add a Virtual Module located (virtually) in the public directory. Other JS files should be able to access this file relatively. For example in the entry file, the /asset/number-one.js can be required like the following.

require('./asset/number-one')

and another random file /something/random.js could require /asset/number-one.js like the following.

require('../asset/number-one')

Actual

Having a problem trying to require a virtual module that is not in the node_modules directory. The following error shows on terminal.

$ npx webpack --config webpack.config.js

Hash: 68ea1406c3585126b4b9
Version: webpack 4.39.3
Time: 85ms
Built at: 09/06/2019 12:23:47 PM
          Asset      Size  Chunks             Chunk Names
index.bundle.js  3.99 KiB   index  [emitted]  index
Entrypoint index = index.bundle.js
[./src/index.js] 52 bytes {index} [built]

ERROR in ./src/index.js
Module not found: Error: Can't resolve './assets/number-one.js' in '/server/node/webpack/custom'
 @ ./src/index.js

Recreate

The following is the code I wrote.

//# FILE: webpack.config.js
const path = require('path');
const VirtualModulesPlugin = require('webpack-virtual-modules');

module.exports = {
  mode: 'development',
  entry: {
    index: './src/index.js'
  },
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'public')
  },
  plugins: [
    new VirtualModulesPlugin({
      'assets/number-one.js': 'module.exports = 1'
    })
  ]
};
//# File: ./src/index.js
require('./assets/number-one.js')

[Bug] virtual module trigger extra compilation in webpack 5

  • I'd be willing to submit the fix

Describe the bug

Using the latest webpack 5 and the latest webpack-virtual-modules.
I notice that webpack is logging out 2 compilation in watch mode.

To Reproduce

Run webpack --watch to reproduce using this brranch: https://github.com/michenly/webpack-5-demo/tree/webpack-virtual-modules-error

Minimally, use webpack-virtual-modules (I did this in both in a plugin with .apply and in webpack config's plugin directly with the same result)

new VirtualModulesPlugin({'test.js': `export default 'test123'`})

Log out compilation message by tapping into compiler.hooks.compile and see two compilation message as soon as webpack --watch is run

Screenshots

Screen Shot 2021-08-11 at 3 22 05 PM

Environment if relevant (please complete the following information):

  • OS: OSX 11.15.1
  • Node version: v12.14.0
  • Mochapack version: ?
  • Webpack version: 5.50.0
  • webpack-virtual-modules version: 0.4.3

Additional context

I also log out complier.removedFiles in compiler.hooks.watchRun, notice how the virtual module is listed as files that was removed.

Does not work with WatchIgnorePlugin

Line 50 of webpack-virtual-modules/index.js breaks when applying WatchIgnorePlugin as the attribute "watcher" is not present on the IngoringWatchFileSystem

if (self._watcher && self._watcher.watchFileSystem.watcher.fileWatchers.length) {

WatchIgnorePlugin rejected a PR. See webpack/webpack#9097

[Feature] Expose types

  • I'd be willing to implement this feature

Describe the user story

While the plugin is written in typescript it does not expose any typings

Describe the solution you'd like

Expose types in the generated and exported code

Describe the drawbacks of your solution

n/a

Describe alternatives you've considered

n/a

Additional context

n/a

[Bug] Uppercase driver letter in windows

  • I'd be willing to submit the fix

Describe the bug

Maybe its not bug but still little annoying. In Vscode ternimal(profile to use cmd.exe or powershell.exe) when using npm build
command, the request from Webpack resolver has a uppercase driver letter, but lowercase when debugging, and they are
different in the CacheBackend._data, so every virtual file webpack-virtual-modules must write twice.

To Reproduce

I create a project show this question at https://github.com/funte/test.
Using Vscode open this project in windows.
Run npm run build command the terminal log path with uppercase driver letter.
Press F5 to debug the terminal log lowercase file path.

Screenshots

If applicable, add screenshots to help explain your problem.

Environment if relevant (please complete the following information):

  • OS: [e.g. OSX, Linux, Windows, ...]
  • Node version [e.g. 8.15.0, 10.15.1, ...]
  • Mochapack version [e.g. 1.1.3, ...]
  • Webpack version [e.g. 4.26.1, ...]

Additional context

Add any other context about the problem here.

Incorrectly used fileWatcher, that causing writeModule not trigger recompile with webpack-dev-server

The incorrect code is below:

if (fileWatcher.path === modulePath) {

In where I print the fileWatcher variable, it likes below:
image

The object structure is defined here in watchpack:
https://github.com/webpack/watchpack/blob/dc690bbaea140820f1d9c7c2ec4dff8902798ff9/lib/watchpack.js#L70

The properties .path and .directoryWatcher is not directly appear in the fileWatcher variable, but fileWatcher.watcher.

When I changed the code to this, it works as expected:
image

[Bug] Compatibility with AngularCompilerPlugin

  • I'd be willing to submit the fix

Describe the bug

With the latest AngularCompilerPlugin, virtual modules are transformed into empty files:

/***/ "./src/virtualentrypoint":
/*!*******************************!*\
  !*** ./src/virtualentrypoint ***!
  \*******************************/
/***/ (() => {

eval("\n\n//# sourceURL=webpack://my-webpack-project/./src/virtualentrypoint?");

/***/ })

Without AngularCompilerPlugin:

/***/ "./src/virtualentrypoint":
/*!*******************************!*\
  !*** ./src/virtualentrypoint ***!
  \*******************************/
/***/ (() => {

eval("console.log(\"this should appear\");\n\n//# sourceURL=webpack://my-webpack-project/./src/virtualentrypoint?");

/***/ })

To Reproduce

Minimal reproduction:
https://github.com/edusperoni/ng-compiler-virtual-modules

Switch useAngularCompiler to false in webpack.config.js and it'll emit on the bundle, switch to true and it'll emit an empty file.

Environment if relevant (please complete the following information):

  • OS: Windows
  • Node version 12.19.0
  • Webpack version 5.36.2

Additional context

Related to #45. Seems to have been introduced with webpack 5 support.

Also, seems to not be an issue with Angular 12 (not yet released)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.