zefoy / ngx-dropzone-wrapper

Angular wrapper library for Dropzone
MIT License
174 stars 51 forks source link

Problem with ssr self is not defined #154

Open azazely85 opened 3 years ago

azazely85 commented 3 years ago

// "../node_modules/ngx-dropzone-wrapper/node_modules/dropzone/dist/dropzone.js": /!***!*\ !** ../node_modules/ngx-dropzone-wrapper/node_modules/dropzone/dist/dropzone.js ! ***/ /! no static exports found / /***/ (function(module, exports, __webpack_require__) {

(function webpackUniversalModuleDefinition(root, factory) { if(true) module.exports = factory(); else { var i, a; } })(self, function() { return /**/ (function() { // webpackBootstrap /**/ var __webpack_modules__ = ({

Error self is not defined

vz-tl commented 3 years ago

Faced same issue in server bundle of our Angular Universal app. In our case window object in SSR environment is properly mocked, but for dropzone.js build webpack obviously has been configured to output as an IIFE, so the code runs into an error before it's even possible to mock the window object.

Right now dropzone is directly imported in dropzone.directive.ts via:

import Dropzone from 'dropzone';

Without changes to dropzone.js I don't see any other solution than replacing the static import with a dynamic one and moving it to ngOnInit after the platform check:

ngOnInit() {
        if (!isPlatformBrowser(this.platformId)) {
            return;
        }
        import('dropzone').then(module => {
          const Dropzone = module.default;
          Dropzone.autoDiscover = false;
         // all remaining code of ngOninit
        }
}

This approach has a small drawback of delaying initialization until lazy-loaded dropzone chunk has been downloaded, but this could be mitigated by emitting an initialized event.

vz-tl commented 2 years ago

Finally fixed the problem by monkey-patching dropzone.js

diff --git a/node_modules/dropzone/dist/dropzone.js b/node_modules/dropzone/dist/dropzone.js
index 6635466..588eb7a 100644
--- a/node_modules/dropzone/dist/dropzone.js
+++ b/node_modules/dropzone/dist/dropzone.js
@@ -1,4 +1,5 @@
 (function webpackUniversalModuleDefinition(root, factory) {
+  if (!root) return;
    if(typeof exports === 'object' && typeof module === 'object')
        module.exports = factory();
    else if(typeof define === 'function' && define.amd)
@@ -7,7 +8,7 @@
        var a = factory();
        for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
    }
-})(self, function() {
+})(typeof self !== 'undefined' && self, function() {
 return /******/ (function() { // webpackBootstrap
 /******/   var __webpack_modules__ = ({
RPbarfield commented 2 years ago

@vz-tl can you give an example of how you monkey-patched dropzone.js? I see the changes you recommended and they work when I modify the actual dropzone.js file, but that's not going to work when others download the dependencies on their end. I appreciate any guidance with this issue. Thanks!

RPbarfield commented 2 years ago

I found a temporary solution until dropzone makes the change OR I shift to another download solution. I included the dropzone.js (with the recommended changes from @vz-tl) in the shared library of my application. I then created a "dropzone" shortcut path in my tsconfig.base.json that points to the modified dropzone.js file in the shared library. It's not a forever fix, but works and the page is able to reload without error-ing out.

@vz-tl Thanks again for the guidance on the dropzone.js change.

vz-tl commented 2 years ago

for monkey-patching node modules it's more convenient to use patch-package.

RPbarfield commented 2 years ago

for monkey-patching node modules it's more convenient to use patch-package.

Awesome module! Thanks for sharing.