webpack-contrib / transform-loader

transform loader for webpack
MIT License
110 stars 23 forks source link

ReferenceError: Can't find variable: fs #13

Closed loretoparisi closed 5 years ago

loretoparisi commented 8 years ago

I get this error: JavaScript console: bundle.js:6091: ReferenceError: Can't find variable: fs

My config file is the following

var path = require('path');
var webpack = require("webpack");

module.exports = {
  entry: './pgapi',
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  module: {
    noParse: /node_modules\/json-schema\/lib\/validate\.js/,
    loaders: [
      { test: /\.json$/, loader: 'json-loader' }
      , {
          test: /\.js$/,
          loader: "transform?brfs"
        }
    ]
  },
  resolve: {
    extensions: ['', '.webpack.js', '.web.js', '.js']
  },
  node: {
    console: true,
    fs: 'empty',
    net: 'empty',
    tls: 'empty'
  },
  plugins: [
        //new webpack.optimize.UglifyJsPlugin(),
        //new webpack.optimize.DedupePlugin(),
        new webpack.DefinePlugin({
            __DEV__: true
        })
    ]
};
loretoparisi commented 8 years ago

I did some tests, the problem happens all times that fs.readFileSync etc. have input parameters specified as variables rather than strings:

$ cat test.js
 var fs  = require('fs');
 var temp = fs.readFileSync('./test.json', 'utf8');
 console.log(temp);
$ node test
{ key : hello world }

$ browserify test.js -o output.js -t brfs
$ node output
{ key : hello world }

$ cat output.js 
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){

 var temp = "{ key : hello world }\n";
 console.log(temp);

},{}]},{},[1]);
$ cat test2.js
 var fs  = require('fs');
 var filename='./test.json';
 var temp = fs.readFileSync(filename, 'utf8');
 console.log(temp);
$ node test2
{ key : hello world }

$ browserify test2.js -o output2.js -t brfs
$ node output2
/output2.js:4
 var temp = fs.readFileSync(filename, 'utf8');
            ^

ReferenceError: fs is not defined
    at Object.__dirname.1 (/output2.js:4:13)
    at s (/output2.js:1:316)
    at e (/output2.js:1:487)
    at Object.<anonymous> (/output2.js:1:505)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.runMain (module.js:575:10)

wepack version is

$ cat node_modules/webpack/package.json | grep id
  "_id": "webpack@1.13.1",
    "webpack-dev-middleware": "^1.0.0",
minwe commented 8 years ago

See https://github.com/substack/brfs/issues/36

https://github.com/substack/brfs/issues/36#issuecomment-62313591

It's impossible to support full inlining in the general case without actually running the files, which runs aground of the halting problem. This module is rather limited in the inputs that it accepts.

minwe commented 8 years ago

As brfs' docs said:

gotchas

Since brfs evaluates your source code statically, you can't use dynamic expressions that need to be evaluated at run time. For example:

// WILL NOT WORK!
var file = window.someFilePath;
var str = require('fs').readFileSync(file, 'utf8');

Instead, you must use simpler expressions that can be resolved at build-time:

var str = require('fs').readFileSync(__dirname + '/file.txt', 'utf8');

So you could not use variable in filename parameter.

loretoparisi commented 8 years ago

@minwe thank you. So I think I have to tweak submodule that are using require('fs').readFileSync like mime or protobuf (just few of them to cite in my case) like parsing those files, searching for everything like

require('fs').readFileSync(fileName) and turn it into something like require('fs').readFileSync(__dirname + fileName)

in a blind way, because I have no idea of what those functions are doing with fs since my package is not using those ones directly.

minwe commented 8 years ago

You can try https://github.com/webpack/raw-loader, it's another choice for file reading.

I'm using brfs, it works well. https://github.com/amazeui/amazeui-react/blob/d335ab5d1ef3434520934a19c11c21bd63d6b75d/docs/accordion/index.js#L8-L9

michael-ciniawsky commented 7 years ago

@loretoparisi @minwe What's the status here 😛? Can this be closed? Following the discussion this seems to be unresolveable by transform-loader?

pabl-o-ce commented 6 years ago

so this is the end.. on this question?

goto-bus-stop commented 6 years ago

@michael-ciniawsky correct, this is not a transform-loader issue

adonespitogo commented 6 years ago

I understand that brfs does not work with variables, but can we at least retain the referrence to var fs = require('fs')?

goto-bus-stop commented 6 years ago

require('fs') would not be able to resolve in the browser and throw an error. https://github.com/browserify/static-module/pull/43 implements scope tracking for brfs and retains the require() call if the variable is still used.

adonespitogo commented 6 years ago

I see. My use case though, is that I'm using this in the server side. I'm trying to obscure my code using webpack and pkg and so I am relying on fs module.

adonespitogo commented 6 years ago

Solved by using raw-loader

alexander-akait commented 5 years ago

Closing due to inactivity. Please test with latest version and feel free to reopen if still regressions. Thanks!