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

support for separate server/client specific vite configurations? #19610

Closed
3 of 4 tasks
daniellacosse opened this issue Mar 12, 2023 · 4 comments
Closed
3 of 4 tasks

support for separate server/client specific vite configurations? #19610

daniellacosse opened this issue Mar 12, 2023 · 4 comments

Comments

@daniellacosse
Copy link

daniellacosse commented Mar 12, 2023

Describe the feature

Thanks to the Nuxt3 team for making such an incredible framework! Admittedly I have a very narrow use case - I'm using the amazingly awesome rollup-obfuscator and to my surprise it actually mostly works - but certain features break the compilation process.

For example, if I use selfDefending, during generation the prerender step hangs forever because I assume we're using vite to prepare some code that then gets further modified in that step - this further modification triggering the self-defense applied, stalling out the process. Super cool to see the obfuscation working as intended, but I really only want to use the obfuscator in the final compilation step anyway.

TL;DR - Having a place to specify a client-specific vite config would I think solve this? And may have other applications.

Additional information

  • Would you be willing to help implement this feature?
  • Could this feature be implemented as a module? (I'm not sure 😅)

Final checks

@daniellacosse
Copy link
Author

daniellacosse commented Mar 12, 2023

For anyone interested, I got around my specific case by writing a script to run against the dist outputted by nuxt generate:

import fs from "node:fs/promises";
import Obfuscator from "javascript-obfuscator";

const obfuscateFile = async javascriptFile =>
  fs.writeFile(
    javascriptFile,
    Obfuscator.obfuscate(
      await fs.readFile(javascriptFile, { encoding: "utf8" }),
      {
        /* ...preferences & secrets... */
      }
    ).getObfuscatedCode()
  );

const remainingFileTree = ["dist"];
while (remainingFileTree.length > 0) {
  const currentFolderOrFile = remainingFileTree.pop();

  if (currentFolderOrFile.endsWith(".js")) {
    console.log(`obfuscating file: ${currentFolderOrFile}`);
    obfuscateFile(currentFolderOrFile);
    continue;
  }

  const fileInformation = await fs.stat(currentFolderOrFile);

  if (fileInformation.isDirectory()) {
    const contents = await fs.readdir(currentFolderOrFile);

    remainingFileTree.push(
      ...contents.map(child => `${currentFolderOrFile}/${child}`)
    );
  }
}

However, this doesn't work with payload extraction, I had to set experimental.payloadExtraction to false in my nuxt.config.ts

Copy link
Member

You can do this at the moment with a Nuxt hook:

export default defineNuxtConfig({
  hooks: {
    'vite:extendConfig': (config, { isClient, isServer }) => {
      // Extend vite config here
    }
  }
})

@Ahidada
Copy link

Ahidada commented Sep 17, 2023

Here's an example.

yarn add javascript-obfuscator -D
yarn add rollup-plugin-obfuscator -D

file: nuxt.config.js

import obfuscatorBox from 'rollup-plugin-obfuscator';

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  devtools: { enabled: true },
  modules: [
    '@nuxt/content'
  ],
  content: {
    documentDriven: true,
    highlight: {
      theme: 'one-dark-pro'
    }
  },
  hooks: {
    'vite:extendConfig': (config, { isClient, isServer }) => {
      // Extend vite config here
      // console.log("config.plugins =", config.plugins);
      if(isClient) {
        config.plugins.push(
          obfuscatorBox({
            global:true,
            options: {
              compact: true,
              controlFlowFlattening: true,
              controlFlowFlatteningThreshold: 0.75,
              numbersToExpressions: true,
              simplify: true,
              stringArrayShuffle: true,
              splitStrings: true,
              splitStringsChunkLength: 10,
              rotateUnicodeArray: true,
              deadCodeInjection: true,
              deadCodeInjectionThreshold: 0.4,
              debugProtection: false,
              debugProtectionInterval: 2000,
              disableConsoleOutput: true, 
              domainLock: [],
              identifierNamesGenerator: "hexadecimal",
              identifiersPrefix: "",
              inputFileName: "",
              log: true,
              renameGlobals: true,
              reservedNames: [],
              reservedStrings: [],
              seed: 0,
              selfDefending: true,
              sourceMap: false,
              sourceMapBaseUrl: "",
              sourceMapFileName: "",
              sourceMapMode: "separate",
              stringArray: true,
              stringArrayEncoding: ["base64"],
              stringArrayThreshold: 0.75,
              target: "browser",
              transformObjectKeys: true,
              unicodeEscapeSequence: true,
  
  
              domainLockRedirectUrl: "about:blank",
              forceTransformStrings: [],
              identifierNamesCache: null,
              identifiersDictionary: [],
              ignoreImports: true,
              optionsPreset: "default",
              renameProperties: false,
              renamePropertiesMode: "safe",
              sourceMapSourcesMode: "sources-content",
  
              stringArrayCallsTransform: true,
              stringArrayCallsTransformThreshold: 0.5,
  
              stringArrayIndexesType: ["hexadecimal-number"],
              stringArrayIndexShift: true,
              stringArrayRotate: true,
              stringArrayWrappersCount: 1,
              stringArrayWrappersChainedCalls: true,
              stringArrayWrappersParametersMaxCount: 2,
              stringArrayWrappersType: "variable",
            },
          }),
        )
      }
    }
  }
})

I'm using the next/content module here. You can remove it

@danielroe
Copy link
Member

This is actually implemented with #22304 and #22302.

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

3 participants