shipshapecode / tether

A positioning engine to make overlays, tooltips and dropdowns better

Home Page:https://tetherjs.dev/docs/welcome

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Static build failure (v1.4.1)

alexsasharegan opened this issue · comments

Trying to compile the latest v1.4.1 into my project fails with this error:

WARNING in ./node_modules/bootstrap-vue/node_modules/tether/dist/js/tether.js
    15:29-36 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
     @ ./node_modules/bootstrap-vue/node_modules/tether/dist/js/tether.js

Any ideas as how this could be? It looks like a standard UMD export, which webpack usually consumes without complaint.

You can see that the path to tether resolves through a peer dep in the bootstrap-vue lib. This error was also present when I installed 1.4.1 for the whole project, but the bootstrap-vue peer dep of latest caused this resolution to nest. I've only managed to compile by removing the nested module, the latest tag from bootstrap-vue, and reverting to 1.4.0.

That's odd. What command are you running that yields that error?

It's running through a webpack bundling process. It doesn't get touched by any loaders, so this should be directly related to webpack's resolution for import Tether from "tether".

Build Command:

cross-env NODE_ENV=production webpack --progress --hide-modules

It's most like the fact that require is used in a way that's not in the format require('some string') and thus is not statically analyzable. Thats gonna work as long as the code path using require isn't hit, but Webpack will whine about it.

You can see in the UMD build that require is passed it to the main body of the function, but never actually used. Just enough for Webpack to see "oh, a require...I'm trying to look at it....but there's nothing I can do at build time with it, help!"

I see. So the dynamic passing of require puts webpack on alert, but since it isn't used, all is well. It looked like the factory return was set on module.exports and that was that—no requires.

I suppose it would be ideal not to pass in require, but I assume that's generated code, and not configurable?

Looks like it's done via gulp-wrap-umd

If you see in the documentation, it passes expressions in the form require('jquery') which is legit as far as Webpack goes and would not have issues here. No idea if it's fixed in a new version (it should just NOT pass in require since there's no dependencies here)

Edit: This is using the latest version here so thats not it

K, im almost sure the solution here would be to change the gulpfile as such here:

 var umdOptions = {
   exports: 'Tether',
   namespace: 'Tether',
   deps: []
 };

None of the dependencies used in the CommonJS part of the UMD template are used, so doing that outputs the right thing.

This is a harmless warning Webpack gives (I think older versions of webpack did not warn for this), but that's how it probably could be fixed.

Update

Looks like the package is being parsed as ESM here and failing. I'm stuck depending on an older version of bootstrap-vue here. Any ideas on how to pull it in?

Error in mounted hook: "TypeError: __WEBPACK_IMPORTED_MODULE_1_tether__.default is not a constructor"

The originating code appears here:

import Tether from 'tether';

I'll try to compile from source for bootstrap-vue and see if that gets webpack to evaluate the export as commonjs.

So I've tried everything, and scanned through lots of source code. I cannot understand why webpack generates the message for the newer versions of tether, nor why it tries loading like an esm default export.

Doing this in the bootstrap-vue source fixes the loading error, but the warning remains:

import { Tether } from 'tether';

I think this just makes webpack fail on the resolution, so it just assigns the default return to the import variable. I've been hunting around webpack issues, and there's definitely some issues around detecting module.exports.__esModule. This would certainly evaluate to false from your source, yet it pulls it in as if it were true. Might be a babel issue? Who the hell knows.

Fixed

Lord only knows what combination fixed this, but here's what I did:

  • Removed the webpack provide plugin from auto-importing Tether (fakes global vars) since nothing relies on it globally available (might have been a leftover setup for bootstrap/bootstrap-vue)
  • Dug into my package-lock.json and wiped out references to tether
  • Updated to latest tether
  • npm install (rebuild package-lock.json)

And it works!

I'm getting the same error, and I'm not using webpack provide plugin..

WARNING in ../node_modules/tether/dist/js/tether.js
7:29-36 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
@ ../node_modules/tether/dist/js/tether.js
@ ../node_modules/react-tether/lib/TetherComponent.js
@ ../node_modules/react-tether/lib/react-tether.js

This is caused due to the require in the transpiled code (/dist) :

(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(factory);
  } else if (typeof exports === 'object') {
    module.exports = factory(require, exports, module);
  } else {
    root.Tether = factory();
  }
}(this, function(require, exports, module) {