antelle / argon2-browser

Argon2 library compiled for browser runtime
https://antelle.net/argon2-browser
MIT License
367 stars 79 forks source link

Integration with create-react-app #38

Closed general-ice closed 4 years ago

general-ice commented 4 years ago

Hi, you made a good job. I've found a problem with create-react-app and i hope you help me) When i try use argon2-browser with my app, which was initialised from create-react-app. So that create-react-app has a only hide webpack config, i've used react-app-rewired to customise it config. Problems: usage process: false dont allowed in create-react-app, because some packadges depend from it, and also i common use the process to acces env variables. If add your suggested config(without process redefining), i have a error __webpack_public_path__ is not defined. Example of problem create-react-app's project bellow package.json:

{
  "name": "myapp",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.4.0",
    "@testing-library/user-event": "^7.2.1",
    "argon2-browser": "^1.12.0",
    "react": "^16.12.0",
    "react-app-rewired": "^2.1.5",
    "react-dom": "^16.12.0",
    "react-scripts": "3.3.0"
  },
  "scripts": {
    "start": "react-app-rewired start"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "devDependencies": {
    "base64-loader": "^1.0.0"
  }
}

config-overrides.js:

 module.exports = {
  webpack: function(config, env) {
    config.module = {
      ...config.module,
      noParse: [/\.wasm$/],
      rules: [
        ...config.module.rules,
        {
          test: /\.wasm$/,
          type: 'javascript/auto',
          loaders: ['base64-loader']
        }
      ]
    }
    config.node = {
      ...config.node,
      __dirname: false,
      fs: 'empty',
      Buffer: false,
    };
    return config
  }
}

usage:

import React from 'react';
import ReactDOM from 'react-dom';
const argon2 = require('argon2-browser')

argon2.hash({ pass: 'password', salt: 'somesalt' })
    .then(h => console.log(h.hash, h.hashHex, h.encoded))
    .catch(e => console.error(e.message, e.code))

ReactDOM.render(
Hello
, document.getElementById('root'));

Thanks in advance

antelle commented 4 years ago

Hi! I've just checked, removing process: false is not an issue, my example works without it as well. I guess, the problem is somewhere not in argon2-browser and you need to debug your webpack config. For example, add things one-by-one and check what fails, on which stage, etc...

chris13524 commented 3 years ago

@general-ice I'm encountering this same issue with create-react-app. Did you ever figure out a solution?

general-ice commented 3 years ago

@chris13524 Hi, Unfortunately,I have not found a good decision. We needed do it fast and used so-so way. All project bundled by webpack, but argon-browser we include via script tag in index.html and use it via global window scope. And if you find good way, please notify me. Thank.

antelle commented 3 years ago

I just gave it a try, so what you need to do in the webpack.config, is the following:

  1. install base64-loader
  2. add to module.rules:
    {
    test: /\.wasm$/,
    loader: "base64-loader",
    type: "javascript/auto",
    },
  3. add to module:
    noParse: /\.wasm$/,
  4. search file-loader (it's somewhere around module.rules[2].oneOf) and add this to exclude:
    /\.wasm$/

    so that it looks something like

    exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/, /\.wasm$/]

I assume @general-ice you were missing the last part, if it's not there, file-loader externalizes all big scripts and it breaks, which generates the error you posted above.

chris13524 commented 3 years ago

@antelle that works! :tada: Thanks for looking into this!

Here's the full config that worked for me:

config.module.rules.push({
    test: /\.wasm$/,
    loader: "base64-loader",
    type: "javascript/auto",
});

config.module.noParse = /\.wasm$/;

config.module.rules.forEach(rule => {
    (rule.oneOf || []).forEach(oneOf => {
        if (oneOf.loader && oneOf.loader.indexOf("file-loader") >= 0) {
            oneOf.exclude.push(/\.wasm$/);
        }
    });
});
antelle commented 3 years ago

Added a link to the readme.
Merry Christmas! 🎄

dwebfan commented 3 years ago

I found same issue and npm start generates

./node_modules/argon2-browser/dist/argon2.wasm
Module parse failed: magic header not detected
File was processed with these loaders:
 * ./node_modules/file-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
Error: magic header not detected

my change is as below.

$ cat config-overrides.js
config.module.rules.push({
    test: /\.wasm$/,
    loader: "base64-loader",
    type: "javascript/auto",
});

config.module.noParse = /\.wasm$/;

config.module.rules.forEach(rule => {
    (rule.oneOf || []).forEach(oneOf => {
        if (oneOf.loader && oneOf.loader.indexOf("file-loader") >= 0) {
            oneOf.exclude.push(/\.wasm$/);
        }
    });
});
$ cat src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
const argon2 = require('argon2-browser')

argon2.hash({ pass: 'password', salt: 'somesalt' })
    .then(h => console.log(h.hash, h.hashHex, h.encoded))
    .catch(e => console.error(e.message, e.code))

ReactDOM.render(document.getElementById('root'));

Can you please help me and point to where I could change?

dwebfan commented 3 years ago

I've figured out the problem. Latest push should be good.