EmberJs and Sodium-plus

Hello Everyone,
What is the generally way to include a dependency that is not an add-on?
I want to include sodium-plus in my app and wrap it in a service.
Following This Advice I’ve added

app.import('node_modules/sodium-plus/index.js');

to my ember-cli-build.js

and in my security service I have:

import Service from '@ember/service';
import {SodiumPlus} from 'sodium-plus';
var sodium;
async function init()
{
  if (!sodium) sodium = await SodiumPlus.auto();
}
init();
export default class SecurityService extends Service {
// other stuff here
}

Unfortunately ember auto import has a problem with this. I’ve included the specific error log at the bottom of this post in case its relevant to anyone in providing an answer. In general how would you incorporate sodium-plus(or any other package) as a dependency into your project?

Version: webpack 4.28.4 Time: 6179ms Built at: 10/05/2020 12:57:39 PM Asset Size Chunks Chunk Names chunk.app.71791af115505cf5c021.js 9.82 KiB app [emitted] app chunk.tests.260001058f2e0abf49b2.js 6.1 KiB tests [emitted] tests chunk.vendors~app.455bcb07daad7bdfcc82.js 4.65 MiB vendors~app [emitted] [big] vendors~app Entrypoint app [big] = chunk.vendors~app.455bcb07daad7bdfcc82.js chunk.app.71791af115505cf5c021.js Entrypoint tests = chunk.tests.260001058f2e0abf49b2.js [0] multi /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/l.js /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js 40 bytes {app} [built] [2] multi /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/l.js /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/tests.js 40 bytes {tests} [built] […/…/…/…/tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js] /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js 1.06 KiB {app} [built] […/…/…/…/tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/l.js] /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/l.js 50 bytes {app} {tests} [built] […/…/…/…/tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/tests.js] /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/tests.js 388 bytes {tests} [built] [./node_modules/@firebase/analytics/dist/index.esm.js] 49 KiB {vendors~app} [built] [./node_modules/@firebase/app/dist/index.cjs.js] 24.9 KiB {vendors~app} [built] [./node_modules/@firebase/auth/dist/auth.js] 247 KiB {vendors~app} [built] [./node_modules/@firebase/database/dist/index.cjs.js] 462 KiB {vendors~app} [built] [./node_modules/@firebase/firestore/dist/index.cjs.js] 489 KiB {vendors~app} [built] [./node_modules/@glimmer/tracking/dist/modules/es2017/index.js] 62 bytes {vendors~app} [built] [./node_modules/firebase/dist/index.cjs.js] 2.64 KiB {vendors~app} [built] [./node_modules/flamelink/dist/index.cjs.js] 1.57 KiB {vendors~app} [built] [./node_modules/sodium-plus/index.js] 1.29 KiB {vendors~app} [built] [./node_modules/swiper/swiper.esm.js] 1.86 KiB {vendors~app} [built] + 156 hidden modules

WARNING in ./node_modules/libsodium/dist/modules/libsodium.js Module not found: Error: Can’t resolve ‘crypto’ in ‘/home/zinhart/Desktop/flamelink-ember/node_modules/libsodium/dist/modules’ @ ./node_modules/libsodium/dist/modules/libsodium.js @ ./node_modules/libsodium-wrappers/dist/modules/libsodium-wrappers.js @ ./node_modules/sodium-plus/lib/backend/libsodium-wrappers.js @ ./node_modules/sodium-plus/index.js @ /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js @ multi /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/l.js /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js

ERROR in ./node_modules/poly1305-js/lib/poly1305.js Module not found: Error: Can’t resolve ‘crypto’ in ‘/home/zinhart/Desktop/flamelink-ember/node_modules/poly1305-js/lib’ @ ./node_modules/poly1305-js/lib/poly1305.js 5:15-32 @ ./node_modules/poly1305-js/index.js @ ./node_modules/sodium-plus/lib/polyfill.js @ ./node_modules/sodium-plus/index.js @ /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js @ multi /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/l.js /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js

ERROR in ./node_modules/sodium-plus/lib/polyfill.js Module not found: Error: Can’t resolve ‘crypto’ in ‘/home/zinhart/Desktop/flamelink-ember/node_modules/sodium-plus/lib’ @ ./node_modules/sodium-plus/lib/polyfill.js 3:15-32 @ ./node_modules/sodium-plus/index.js @ /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js @ multi /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/l.js /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js

ERROR in ./node_modules/node-gyp-build/index.js Module not found: Error: Can’t resolve ‘fs’ in ‘/home/zinhart/Desktop/flamelink-ember/node_modules/node-gyp-build’ @ ./node_modules/node-gyp-build/index.js 1:9-22 @ ./node_modules/sodium-native/index.js @ ./node_modules/sodium-plus/lib/backend/sodiumnative.js @ ./node_modules/sodium-plus/index.js @ /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js @ multi /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/l.js /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js

ERROR in ./node_modules/node-gyp-build/index.js Module not found: Error: Can’t resolve ‘os’ in ‘/home/zinhart/Desktop/flamelink-ember/node_modules/node-gyp-build’ @ ./node_modules/node-gyp-build/index.js 5:9-22 @ ./node_modules/sodium-native/index.js @ ./node_modules/sodium-plus/lib/backend/sodiumnative.js @ ./node_modules/sodium-plus/index.js @ /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js @ multi /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/l.js /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js

ERROR in ./node_modules/libsodium/dist/modules/libsodium.js Module not found: Error: Can’t resolve ‘path’ in ‘/home/zinhart/Desktop/flamelink-ember/node_modules/libsodium/dist/modules’ @ ./node_modules/libsodium/dist/modules/libsodium.js 40:21-36 42:81-96 5529:19-34 5531:79-94 @ ./node_modules/libsodium-wrappers/dist/modules/libsodium-wrappers.js @ ./node_modules/sodium-plus/lib/backend/libsodium-wrappers.js @ ./node_modules/sodium-plus/index.js @ /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js @ multi /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/l.js /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js

ERROR in ./node_modules/node-gyp-build/index.js Module not found: Error: Can’t resolve ‘path’ in ‘/home/zinhart/Desktop/flamelink-ember/node_modules/node-gyp-build’ @ ./node_modules/node-gyp-build/index.js 3:11-26 @ ./node_modules/sodium-native/index.js @ ./node_modules/sodium-plus/lib/backend/sodiumnative.js @ ./node_modules/sodium-plus/index.js @ /tmp/broccoli-2037uNsZtLxKguBa/cache-268-bundler/staging/app.js Build Error (Bundler)

webpack returned errors to ember-auto-import

Stack Trace and Error Report: /tmp/error.dump.d5277ab95c257ebd20b9b0b440fb07f1.log

When using ember-auto-import to add a dependency, you don’t also need app.import(). You should use one or the other.

I’ll show both ways here. Usually I would just say to use ember-auto-import, but it looks like sodium-plus is distributed in a way that’s actually pretty awkward to use from within webpack (which is what ember-auto-import is using).

To make it work in ember-auto-import

  1. Delete your app.import() line, it’s not needed.

  2. Update ember-cli-build.js to tell webpack to use their browser specific build (which is located under dist/sodium-plus) and tell webpack to ignore the “missing” crypto and fs dependencies:

    module.exports = function(defaults) {
      let app = new EmberApp(defaults, {
        // Add options here
        autoImport: {
          alias: {
            'sodium-plus': 'sodium-plus/dist/sodium-plus'
          },
          webpack: {
            node: {
              crypto: 'empty',
              fs: 'empty',
            }
          }
        }
      });
    
  3. Update your code so it doesn’t try to use the exports from their module, because there aren’t any. Unfortunately, the sodium-plus browser build installs itself via globals instead:

    import "sodium-plus";
    (async function() {
      console.log(await sodium.randombytes_buf(32));
    })();
    

To make it work with app.import()

  1. Change your app.import to point at their browser-specific build:

     app.import('node_modules/sodium-plus/dist/sodium-plus.js');
    
  2. In your code, don’t try to import anything. Instead, just use the sodium global directly. You can see the full set of globals they create here.

1 Like

Hello ef4,

Thanks for the clarification this is exactly what I needed.