Giter Site home page Giter Site logo

closure-loader's Introduction

closure-loader

npm deps test

This is a Webpack loader which resolves goog.provide() and goog.require() statements in Webpack as if they were regular CommonJS modules.

Installation

npm install --save-dev closure-loader

Usage

Documentation: Using loaders

NOTE: This loader is mainly meant for building (probably older) Closure Compiler projects with Webpack and to make a transition to other module systems (CommonJS or ES6) easier.

There are two parts to this loader:

  • goog.provide()
    • Basically just creates the given namespace in the local scope of that module
    • Any file containing this statement will be added to a map for require lookups
  • goog.require()
    • Like goog.provide() it creates the given namespace in the scope of that module
    • It finds the corresponding file with the goog.provide() statement and loads it (see configuration below)
    • It assigns the value of the namespace from the provide file and assign it to the same namespace in the current module

In the simplest way you can just use those two statements like you usually would with Google Closure Tools.

NOTE: Usually the Closure compiler simply creates all namespaces on the global scope (i.e. the window object). This is not the case if you use this loader. Every file ("module") has its own scope just like it would have if you used CommonJS syntax.

You can use Closure dependencies in conjunction with CommonJS syntax. You can load any module that uses goog.provide() with require(), but not the other way round.

// module.js
goog.provide('my.app.module');

my.app.module = function () {
    console.log('my module was loaded');
}

// index.js
var module = require('./module.js').my.app.module;

module(); // will output 'my module was loaded' to the console

ES6 Modules

If you use babel you can even use ES6 import syntax. If you have enabled the es6mode in the loader config the first goog.provide() of each file will be exported as "default" in addition to its full namespace.

// module.js
goog.provide('my.app.module');

my.app.module = function () {
    console.log('my module was loaded');
}

// index.js
import module from './module.js';
// is the same as
var module = require('./module.js').default;
// or
var module = require('./module.js').my.app.module;

module(); // will output 'my module was loaded' to the console

Configuration

Here is an example Webpack config for this loader:

module.exports = {
    entry: {
        app: './src/index.js'
    },
    output: {
        path: './build',
        filename: '[name].js'
    },
    module: {
        rules: [
            {
                test: /\/src\/.*\.js$/,
                loader: 'closure-loader',
                options: {
                    paths: [
                        __dirname + '/src',
                    ],
                    es6mode: true,
                    watch: true,
                    fileExt: '.js',
                },
                exclude: [/node_modules/, /test/]
            }
        ]
    },
};

Here are the configuration options specific for this loader:

  • paths (array): An array of path strings. The loader will search all *.js files within theses paths for goog.provide() statements when resolving a goog.require(). You can only goog.require() dependencies that can be found under one of these paths.
  • es6mode (boolean, default: false): If enabled it will add the value of the first goog.provide() as default export for usage with babel. For this reason it will also export the corresponding flag module.exports.__esModule = true
  • watch (boolean, default: true): If true, the loader will intitialise watchers which check for changes in the mapped files. This is neccesary to be able to delete the internal map cache. But it also makes problems with CI sytstems and build scripts, because the watcher will prevent the process from beeing exited.
  • fileExt (string, default: '.js'): Files extension which will be searched for dependency resolving. Support glob pattern syntax.

NOTE: This loader in no way includes or wraps the actual Google Closure Library. If you want to use the Closure Library you will have to include it yourself and ensure correct shimming:

module: {
    rules: [
        {
            test: /google-closure-library\/closure\/goog\/base/,
            use: [
                'imports-loader?this=>{goog:{}}&goog=>this.goog',
                'exports-loader?goog',
            ],
        },
    ],
},
plugins: [
    new webpack.ProvidePlugin({
        goog: 'google-closure-library/closure/goog/base',
    }),
]

Authors

  • Steven Weingärtner - Original author & maintainer - eXaminator
  • Matt Mulder - Current maintainer - mxmul

See also the list of contributors who participated in this project.

License

MIT (http://www.opensource.org/licenses/mit-license.php)

closure-loader's People

Contributors

alekstorm avatar anmonteiro avatar bendavis78 avatar configurator avatar dependabot[bot] avatar examinator avatar gitter-badger avatar johanatan avatar micha149 avatar mxmul avatar occar421 avatar petrleocompel avatar prachp 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

Watchers

 avatar  avatar  avatar  avatar

closure-loader's Issues

global namespaces being polluted by deep-extend

I'm seeing an issue where namespaces that are exposed as globals (e.g. via goog.exportSymbol) can get polluted (new keys are added to the global, or existing keys replaced with empty object) when imported by another Closure module. Example:

app.js:

goog.require('some.namespace.foo');
goog.require('some.namespace.bar');

console.log([
  some.namespace.foo,
  some.namespace.bar,
  window.some.namespace.foo,
  window.some.namespace.bar,
]);

foo.js

goog.provide('some.namespace');
goog.provide('some.namespace.foo');

some.namespace = some.namespace || {};

some.namespace.foo = 1;

goog.exportSymbol('some.namespace.foo', some.namespace.foo);

bar.js

goog.require('some.namespace');
goog.require('some.namespace.foo');
goog.provide('some.namespace.bar');

some.namespace.bar = 2

I would expect the output of app.js to be [1, 2, 1, undefined], but it is actually [1, 2, {}, 2]. I think that the root of the problem is that the module prefix generated by closure-loader uses deep-extend without an empty object as the first argument – so requiring any namespace that's available as a global may mutate it.

How to disable strict mode with loader?

When a file is imported with strict mode enabled, the resolution fails.

eval('var x=__merge(x||window.x||{},{"soy":{"examples":{"thing":{}},"thing":{}}});var soy=__merge(soy||window.soy||{},{});var soydata=__merge(soydata||window.soydata||{},{});');

It looks like this line is executing correctly, however, when I try to assign soy on the very next line, an error is thrown because strict mode is prepended to the file via webpack.

Causes "Uncaught TypeError: Cannot set property '???' of undefined" in some cases.

Hi, thank you for this loader 😄

I recently found the problem on this loader when I tried this loader to solve the dependency.
In some cases, it causes "Uncaught TypeError: Cannot set property '???' of undefined".
I assume it has bug during the empty object generation from this loader.

In '2.js' in demo...

1

2

a.b.c.g is prepared.

 
3

a.b.c.d is erased!

 
4

Then, a.b.c.g.bar = function () {/* ... */} causes error becuase a.b.c.g is not defined anymore.

(Windows 10, Chrome 66)

I confirmed that it runs well on the bundled js file generated by Google's Closure Compiler.

Demo: https://github.com/occar421/demo-for-issue/tree/master/closure-loader--1
(This is not minimum but enough to show the problem.)
You can see the difference of the behavior between yarn start (closure-loader) and yarn build + yarn run serve (google-closure-compiler) on 'public/index.html'.

Regards.

Error on commented goog.provide statement

A commented goog.provide statement can cause an error if es6mode is enabled and it is the first goog.provide statement in a file. The loader will still create the module.exports entry at the bottom of the file.

ERROR in ./content/closure-polyfill.js Module build failed: Error: Can't find closure dependency goog.debug

module: {
rules: [
{
oneOf: [
{
test: [/.bmp$/, /.gif$/, /.jpe?g$/, /.png$/],

        loader: "url-loader",
        options: {
          limit: 10000,
          name: "media/[name].[hash:8].[ext]"
        }
    },
    {
        test: /google-closure-library\/closure\/goog\/base/,
        use: [
          "imports-loader?this=>{goog:{}}&goog=>this.goog",
          "exports-loader?goog"
        ]
    },
    {
        test: /google-closure-library\/closure\/goog\/.*\.js/,
        loader: "closure-loader",
        options: {
          paths: [
            path.resolve(__dirname, "node_modules/google-closure-library/closure/goog"),
            path.resolve(__dirname, "node_modules/google-closure-library/closure/goog/debug")
          ],
          watch: false,
          es6mode: true
        },
        exclude: [/google-closure-library\/closure\/goog\/base\.js$/]
    },
    {
        test: /selenium-atoms\/.*\.js$/,
        include: [
          path.resolve(__dirname, "src")
        ],
        use: {
          loader: "closure-loader",
          options: {
            es6mode: true,
            watch: false,
            paths: [
              path.resolve(__dirname, "node_modules/google-closure-library/closure/goog"),
              path.resolve(__dirname, "node_modules/google-closure-library/closure/goog/debug"),
              path.resolve(__dirname, "src/selenium-atoms")
            ]
          }
        }
    },
    {
        test: /third_party\/wgxpath\/.*\.js$/,
        include: [
          path.resolve(__dirname, "src")
        ],
        use: {
          loader: "closure-loader",
          options: {
            es6mode: true,
            watch: false,
            paths: [
               path.resolve(__dirname, "node_modules/google-closure-library/closure/goog")
            ]
          }
        }
    },
    {
        test: /atoms\/.*\.js$/,
        include: [
          path.resolve(__dirname, "src")
        ],
        use: {
          loader: "closure-loader",
          options: {
            es6mode: true,
            watch: false,
            paths: [
              path.resolve(__dirname, "node_modules/google-closure-library/closure/goog"),
              path.resolve(__dirname, "node_modules/google-closure-library/closure/goog/debug"),
              path.resolve(__dirname, "src/third_party/wgxpath"),
              path.resolve(__dirname, "src/atoms")
            ]
          }
        }
    },
    {
        test: /closure-polyfill\.js$/,
        include: [
          path.resolve(__dirname, "src")
        ],
        use: {
          loader: "closure-loader",
          options: {
            es6mode: true,
            watch: false,
            paths: [
              path.resolve(__dirname, "node_modules/google-closure-library/closure/goog"),
              path.resolve(__dirname, "src/atoms"),
              path.resolve(__dirname, "src/selenium-atoms")
            ]
          }
        }
},
    // Process JS with Babel.
    {
        test: /\.(jsx?)$/,
        include: [
          path.resolve(__dirname, "src")
        ],
        use: [
          {
            loader: "babel-loader",
            options: {
              compact: true
            }
          }
        ]
    },
// Process css
    {
        test: /\.css$/,
        loader: [
          require.resolve("style-loader"),
          {
            loader: require.resolve("css-loader"),
            options: {
              importLoaders: 1
            }
          },
        ]
        // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
    },
// Process markdown to string, to be included inside the bundle, instead of as file
    {
        test: /\.md$/,
        loader: "raw-loader"
    },
{
        loader: "file-loader",
        exclude: [/\.jsx?$/, /\.html$/, /\.json$/],
        options: {
          name: "media/[name].[hash:8].[ext]"
        }
      }
 // ** STOP ** Are you adding a new loader?
     // Make sure to add the new loader(s) before the "file" loader.
]
  }
]

I am using the above rules in my webpack.config.js file

Resolving only JS files - Not respecting configuration

Problem is this line - dependencyMapBuilder.js:64

return glob(path.join(directory, '/**/*.js'));

You are resolving only JS files which is not correct, because you are not respecting configuraction.

My webpack loaders configuration

{
    test: /\.jsx$/,
    exclude: [/node_modules/, /\/src\/lib\/.*/g],
    loaders: ['closure-loader', 'babel-loader']
},
{
    test: /\.js?$/,
    exclude: [/node_modules/,  /\/src\/lib\/.*/g],
    loaders: ['closure-loader']
}

So if file is JSX then i want it load by babel-loader and then by closure-loader.
If i override dependencyMapBuilder.js:64 to this than it is working ok.

return glob(path.join(directory, '/**/*.js?(x)'));

But there should be something like this

return glob(path.join(directory, '/**/' + convertedFileTestFromWebpackFromConfig));

Maybe i will try to make pull request.

Webpack 4 Support

Just wondering if you've tested this loader with webpack 4? I'm having some issues myself.

Update Examples

I am currently going through the examples to load in the google closure library and I am getting errors with webpack 3.6.0. It is possible I am doing something wrong, but I think the webpack configs are simply out of date.

Too much overhead

It looks like the closure loader creates too much overhead when adding its own code to usercode. This causes a lot of file size bloating.

Support for ES6 'goog:foo.bar.baz' imports

The latest versions of google closure support es6 modules, as well as closure-specific module syntax in the form of import foo from 'goog:foo.bar.baz'. This allows for files (for example, the google closure js library itself) to continue to goog.provide('foo.bar.baz') while having their code imported into es6 modules.

Would it be simple to make this work with the loader, and correctly resolve both new- and old-style imports/requires? I've had a first attempt at modifying the loader, adding an additional regex in the form of ^import (.+) from ['"]goog:(.+)['"], but can't get things working yet: I intend to continue testing this out but thought I'd post here in the meantime in case there's any existing work on this or any roadblocks I'm overlooking.

Just to clarify, my intention would be only to transpile these special prefixed imports, and leave the pure es6 imports down to something like babel-loader since that feels more appropriate.

ERROR in ./content/closure-polyfill.js Module build failed: Error: Can't find closure dependency bot

I am trying to compile the selenium-ide-3.4.4 source. I have installed all the dependencies using npm install and update. Also ran peru sync command. However, on running npm run build
i am getting the following error:

ERROR in ./content/closure-polyfill.js
Module build failed: Error: Can't find closure dependency bot
at replaceRequire (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/closure-loader/lib/index.js:39:15)
at mapBuilder.then.provideMap (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/closure-loader/lib/index.js:253:26)
at tryCatcher (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:517:31)
at Promise._settlePromise (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:574:18)
at Promise._settlePromise0 (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:619:10)
at Promise._settlePromises (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:699:18)
at Promise._fulfill (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:643:18)
at Promise._resolveCallback (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:437:57)
at Promise._settlePromiseFromHandler (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:529:17)
at Promise._settlePromise (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:574:18)
at Promise._settlePromise0 (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:619:10)
at Promise._settlePromises (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:699:18)
at Promise._fulfill (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:643:18)
at MappingPromiseArray.PromiseArray._resolve (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise_array.js:126:19)
at MappingPromiseArray._promiseFulfilled (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/map.js:101:18)
at Promise._settlePromise (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:579:26)
at Promise._settlePromise0 (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:619:10)
at Promise._settlePromises (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:699:18)
at Promise._fulfill (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:643:18)
at Promise._resolveCallback (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:437:57)
at Promise._settlePromiseFromHandler (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:529:17)
at Promise._settlePromise (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:574:18)
at Promise._settlePromise0 (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:619:10)
at Promise._settlePromises (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:699:18)
at Promise._fulfill (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:643:18)
at MappingPromiseArray.PromiseArray._resolve (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise_array.js:126:19)
at MappingPromiseArray._promiseFulfilled (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/map.js:101:18)
at Promise._settlePromise (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:579:26)
at Promise._settlePromise0 (/root/selenium-ide-3.4.4/packages/selenium-ide/node_modules/bluebird/js/release/promise.js:619:10)
@ ./content/commands-api.js 16:135-164
@ multi ./content/commands-api

Please assist to resolve this issue

Thanks.

Cannot find module 'loader-utils'

Hello, thanks for this project. I wanted to try running the example code but can't get past the following error:

$ npm install
...
$ npm run build

> [email protected] build /Users/jb/code/closure-loader/examples/es6-closure-lib
> webpack

Hash: defc3590a0fcc5535c4b
Version: webpack 1.12.13
Time: 2358ms
     Asset       Size  Chunks             Chunk Names
    app.js    2.36 kB       0  [emitted]  app
app.js.map    2.16 kB       0  [emitted]  app
index.html  323 bytes          [emitted]
    + 2 hidden modules

ERROR in Cannot find module 'loader-utils'
 @ ./src/app.js 5:46-101

I've tried installing loader-utils explicitly, but it still can't be found. It's possible I'm doing something silly here, or perhaps something's changed with one of the libraries since the examples were written? I couldn't find anything helpful on the first couple of pages of Google.

Webpack peer dependecy version

I think there is no need to lock on Webpack v1. It works on Webpack v2 (Tested with 2.4.1)
Please allow as peer dependency Webpack v2 also.

shimming for closure library - goog.global

This is only an issue with the examples not the loader itself.

When importing some modules from closure library (the rich text editor in particular) you end up with issues caused by the fact that when loading the base.js file the this argument is not the window object it is expecting.

It seems the goog.global is built on top of the window object and in many modules such as labs/useragent/util rely on that fact for access to window properties such as "navigator"

using the shim shown in the examples these properties and methods are missing which obviously causes subtle bugs. The only way I've found so far to solve this looks seriously ugly; when loading the base file in webpack I've modified the imports section.

"imports-loader?this=>function() { window['goog'] = window['goog'] ? window['goog'] : {}; return window; }()&goog=>this.goog"

I think it's just my lack of understanding of how the mechanics of this all work, would really appreciate any thoughts on what I'm doing wrong?

Build problem on legacy-closure-lib

Hi,

I'm having problem trying to make work the legacy-closure-lib example, I got the error:

ERROR in multi app
Module not found: Error: Cannot resolve module 'closure' in /tmp/closure-loader/examples/legacy-closure-lib
 @ multi app

when running the webpack build.

here are the steps i've done to produce the bug:

  • git clone [email protected]:eXaminator/closure-loader.git
  • cd closure-loader/
  • npm install
  • cd examples/legacy-closure-lib/
  • npm install
  • npm start

npm version: 3.7.5

goog.provide() broken if goog.require() used on a parent module

For example:

goog.provide('goog.style.bidi');

goog.require('goog.dom');
goog.require('goog.style');
goog.require('goog.userAgent');

This gets converted to:

goog.dom=require("./../dom/dom.js").goog.dom;
goog.style=require("./style.js").goog.style;
goog.userAgent=require("./../useragent/useragent.js").goog.userAgent;

The goog.style.bidi variable gets overidden because goog.style is re-assigned afterward.

Fix source maps

When using the loader it injects a few lines of code into all loaded source files but doesn't update the source map correctly. This should be changed. The import-loader is a good example on how to do this.

Webpack 2 example

Is there a working example using Webpack 2?
I'm getting the following error: configuration has an unknown property 'closureLoader'.

Uncaught ReferenceError: goog is not defined

I tried to follow README, but all I get is Uncaught ReferenceError: goog is not defined.

Here is my webpack config:

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

module.exports = {
  context: path.join(__dirname, '/src'),

  entry: {
    app: [
      'webpack-dev-server/client?http://localhost:8080/assets/',
      'webpack/hot/only-dev-server',
      './app.js'
    ]
  },

  output: {
    filename: '[name].js',
    path: path.join(__dirname, '/dist'),
    publicPath: '/assets/'
  },

  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
  ],

  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loaders: ['react-hot', 'babel-loader', 'closure-loader']
      },
      {
        test: /\.html$/,
        loader: "file?name=[name].[ext]"
      }
    ]
  },

  closureLoader: {
    paths: [
      path.join(__dirname, 'node_modules', 'google-closure-library', 'closure'),
      path.join(__dirname, '/src')
    ],
    es6mode: true
  }
}

goog.scope + compiler

Hi,

To start off, thank you for this loader. Has been very helpful so far. I've never used Closure and just recently inherited a program that uses Closure and now looking to build it via Webpack (currently builds with Bazel). In the source code, there's a lot of :
goog.provide()
and
goog.require()

both which seem to be supported by this project. The only difference that I see in the project that I'm working on is that after goog.provide and good.require , the implementation is wrapped in scope. e.g.

goog.provide('myApp.module');
goog.require('goog.asserts');

goog.scope(function(){
  myApp.module = function () { return "hi" }
}

Does this library use of JS modules make this goog.scope obsolete? If not, is there a way to use it via the Closure library that's included?

Also, a bit different, but I'm not really sure how this project fits with the google closure compiler. Theoretically speaking, is this all I need to have a functioning JS app with Closure Library without the need of the compiler? Is the compiler merely an optimizer?

Thanks in advance!!

Make eval optional

It would be nice to control the use of eval in the namespace definitions. This has led to some issues in compiling and executing code on a local project.

Module build failed: Error: Can't find closure dependency goog.xxx

Followed the example in es6-webpack2 I've found I can't make closure-loader work:

ERROR in ./node_modules/google-closure-library/closure/goog/crypt/sha1.js
Module build failed: Error: Can't find closure dependency goog.crypt.Hash

my webpack.config.js is:

var HtmlWebpackPlugin = require('html-webpack-plugin'),
    webpack = require('webpack'),
    pathUtil = require('path');

module.exports = {
  entry: {
    app: './src/index.js'
  },
  output: {
    filename: 'bundle.js',
    path: __dirname + '/dist'
  },
  resolveLoader: {
    modules: ['closure-loader', pathUtil.resolve(__dirname, 'node_modules')]
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loaders: ['closure-loader'],
      },
    ]
  }
};

my js file is very simple:

import Sha1 from 'google-closure-library/closure/goog/crypt/sha1';

import _ from 'lodash';

function component() {
  var element = document.createElement('div');
  var sha1 = new Sha1();
  sha1.update("foobar");
  var hash = sha1.digest();

  element.innerHTML = _.join(['Hello', 'webpack', hash], ' ');

  return element;
}

document.body.appendChild(component());

Thanks!

Cannot read property 'config' of null

Having some issues with closure-loader 0.9.1. I'm trying to run some tests with karma and it looks like this call (line 216 in index.js) always returns a null object for my tests. Any ideas?

    const options = loaderUtils.getOptions(this);

This options object is asked for a config value later in that code and since options is null it crashes out.

Versions:

webpack: 4.10.2
closure-loader: 0.9.1
google-closure-library: v20160911.0.0
karma-webpack: 3.0.0

Thanks!

This package is no longer maintained

I will no longer maintain this package as I don't have enough time and I don't use it anymore myself.

If anyone wants to take over just get in touch.

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.