Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Activestorage npm import causes File Not Found error. #34586

Closed
andrew-oko-odion opened this issue Dec 1, 2018 · 13 comments
Closed

Activestorage npm import causes File Not Found error. #34586

andrew-oko-odion opened this issue Dec 1, 2018 · 13 comments

Comments

@andrew-oko-odion
Copy link

Actual behavior

import { DirectUpload } from 'activestorage';
causes this error

ReferenceError: File is not defined
    at Object.<anonymous> (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:6854)
    at e (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:392)
    at Object.defineProperty.value (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:1742)
    at e (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:392)
    at Object.<anonymous> (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:4863)
    at e (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:392)
    at Object.<anonymous> (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:3685)
    at e (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:392)
    at Object.<anonymous> (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:3471)
    at e (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:392)
    at Object.e.a (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:2605)
    at e (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:392)
    at e.d (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:749)
    at /home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:758
    at r (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:143)
    at Object.<anonymous> (/home/niceguy/workspace/javascript/next/networkTest/node_modules/activestorage/app/assets/javascripts/activestorage.js:1:269)

System configuration

React config:

 "activestorage": "^5.2.1-1",
  "express": "^4.16.4",
  "next": "^7.0.2",
  "react": "^16.6.3",
  "react-dom": "^16.6.3",
@javan
Copy link
Contributor

javan commented Dec 2, 2018

causes this error

Causes it when? In a browser? When building with webpack or some other tool?

@javan javan added activestorage more-information-needed When reporter needs to provide more information labels Dec 2, 2018
@andrew-oko-odion
Copy link
Author

Here is my full package.json

{
  "name": "create-next-example-app",
  "scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "NODE_ENV=production node server.js"
  },
  "dependencies": {
    "@zeit/next-css": "^1.0.1",
    "activestorage": "^5.2.1-1",
    "express": "^4.16.4",
    "isomorphic-unfetch": "^3.0.0",
    "lodash": "^4.17.11",
    "next": "^7.0.2",
    "react": "^16.6.3",
    "react-dom": "^16.6.3",
    "semantic-ui-css": "^2.4.1",
    "semantic-ui-react": "^0.83.0"
  },
  "devDependencies": {
    "css-loader": "^1.0.1",
    "file-loader": "^2.0.0",
    "url-loader": "^1.1.2",
    "webpack": "^4.25.1"
  }
}

@rails-bot rails-bot bot removed the more-information-needed When reporter needs to provide more information label Dec 2, 2018
@javan
Copy link
Contributor

javan commented Dec 2, 2018

Thanks, but that's not a reproducible test case. I can't run any of those commands without actual files to build.

@javan
Copy link
Contributor

javan commented Dec 2, 2018

My guess is you're trying to build activestorage for node, which does not have a File constant, like browsers do. activestorage.js is designed for the browser.

@andrew-oko-odion
Copy link
Author

Thanks @javan, you just offered a very good insight.
I am not still sure how to make it work with my node/webpack setup.

But I will definitively try out UMD build.

In the mean time, this issue is still not resolved. to reproduce, setup a nextjs application and include activestorage using yarn. The error would definately popup, especially when are using a custom node server.
I am very surprise that others have used activestorage.js on their React application, as seen in other issues but yet, no one reported its issue with bundling with nodejs.

@andrew-oko-odion
Copy link
Author

No UMD build anywhere.

@andrew-oko-odion
Copy link
Author

Even Runkit on NPM spotted it too.
screenshot from 2018-12-03 14-35-34

@javan
Copy link
Contributor

javan commented Dec 3, 2018

I am very surprise that others have used activestorage.js on their React application, as seen in other issues but yet, no one reported its issue with bundling with nodejs.

The issue isn't bundling with nodejs, it's running activestorage.js in a node environment. I believe nextjs compiles your code to run on both the server and browser, correct? You'll need to configure it to only include activestorage.js in the browser bundle. How that's done is beyond the scope of Rails support.

No UMD build anywhere.

activestorage.js is a UMD module:

output: {
file: "app/assets/javascripts/activestorage.js",
format: "umd",
name: "ActiveStorage"

Even Runkit on NPM spotted it too.

Runkit is a nodejs environment so, same issue.


I've confirmed that the code example you provided works fine in the browser:

import { DirectUpload } from 'activestorage';

👇

https://glitch.com/edit/#!/sour-geese?path=src/index.js:1:0

👇

https://sour-geese.glitch.me/

@manoelneto
Copy link

I'm having same issue when I'm trying to import the file_checksum.js file.

the only problem to make this code compile in server side is to move the cons fileSlice definition to a function, so we'll defer it's initialization

import SparkMD5 from "spark-md5"

# This won't work because File doesn't exists at server side
const fileSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice

but this will work

import SparkMD5 from "spark-md5"

const getFileSlice = () => File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice

So I kinda copy this file to my project and updated to use this syntax. Hope it helps anyone

@AdnanTheExcellent
Copy link

AdnanTheExcellent commented Feb 5, 2021

If anyone is trying to get activestorage working with server side rendering, you can do the following:

create a file activestorageStub.js (or ts) that has the following line:

export const DirectUpload = null;

then in webpack, add it as an alias:

const path = require('path');

if (ssr) {
  resolve.alias = {
    activestorage: path.resolve(PATH, TO, FILE, 'activestorageStub.js'),
  }
}

@danvernon
Copy link

If anyone is trying to get activestorage working with server side rendering, you can do the following:

create a file activestorageStub.js (or ts) that has the following line:

export const DirectUpload = null;

then in webpack, add it as an alias:

const path = require('path');

if (ssr) {
  resolve.alias = {
    activestorage: path.resolve(PATH, TO, FILE, 'activestorageStub.js'),
  }
}

@AdnanTheExcellent can you share your webpack config in whole? kind of new to running custom nextjs webpack

@r-ogarkov
Copy link

For TS

tsconfig.json

"activestorage": [
  "path/to/custom/activestorage"
]

path/to/custom/activestorage.js

module.exports = {
  DirectUpload:
    typeof window !== "undefined"
      ? require("activestorage/app/assets/javascripts/activestorage").DirectUpload
      : null,
};

declare module

declare module "activestorage" {
  export as namespace ActiveStorage;

  export function start(): void;

  export class DirectUpload {
    id: number;
    file: File;
    url: string;

    constructor(file: File, url: string, delegate?: DirectUploadDelegate);

    create(callback: (error: Error, blob: Blob) => void): void;
  }

  export interface DirectUploadDelegate {
    directUploadWillCreateBlobWithXHR?:
      | ((xhr: XMLHttpRequest) => void)
      | undefined;

    directUploadWillStoreFileWithXHR?:
      | ((xhr: XMLHttpRequest) => void)
      | undefined;
  }

  export interface Blob {
    byte_size: number;
    checksum: string;
    content_type: string;
    filename: string;
    signed_id: string;
  }
}

import

import { DirectUpload } from "activestorage";

@fcandi
Copy link

fcandi commented Feb 23, 2022

Hi,

I just have come across this because I am refacturing my app from vanilla React to Next.JS.

I found a very easy way to deal with this problem by using the dynamic import feature from Next.js with the option ssr: false.

So I import DirectUpload (in my Case I use DirectUploadProvider) like this:

const DirectUploadProviderNoSSR = dynamic(() =>
    import('react-activestorage-provider').then((mod) => mod.DirectUploadProvider),
    { ssr: false }
)

And change the Component Name in the code to "DirectUploadProviderNoSSR" accordingly.

Also see the Next.JS docs here.

Andreas

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants