All files / vue-cli-plugin-electron-builder/lib webpackConfig.js

90.63% Statements 58/64
88.57% Branches 31/35
100% Functions 11/11
90.48% Lines 57/63

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 1422x 2x       34x 34x 34x   31x   31x         31x 31x 31x 31x                 31x   30x 30x 30x 30x 30x 30x   1x   1x 1x 1x       31x     34x                               34x       31x 31x 31x   2x     29x   31x 31x   12x 6x 6x   6x   31x 31x     27x   27x   29x   27x     27x     27x     27x 27x 6x   27x 27x       62x                 13x           27x       31x 31x   13x   31x   2x  
const fs = require('fs')
const { DefinePlugin } = require('webpack')
 
async function chainWebpack (api, pluginOptions, config) {
  const rendererProcessChain =
    pluginOptions.chainWebpackRendererProcess || (config => config)
  const realDirname = 'require("electron").remote.app.getAppPath()'
  if (process.env.IS_ELECTRON) {
    // Add externals
    config.externals(getExternals(api, pluginOptions))
    //   Modify webpack config to work properly with electron
    config
      .target('electron-renderer')
      .node.set('__dirname', false)
      .set('__filename', false)
    // Set IS_ELECTRON
    Eif (config.plugins.has('define')) {
      config.plugin('define').tap(args => {
        args[0]['process.env'].IS_ELECTRON = true
        return args
      })
    } else {
      config.plugin('define').use(DefinePlugin, [
        {
          'process.env': { IS_ELECTRON: true }
        }
      ])
    }
    if (process.env.NODE_ENV === 'production') {
      //   Set process.env.BASE_URL and __static to absolute file path
      config.plugin('define').tap(args => {
        args[0].__dirname = realDirname
        args[0].__filename = `\`\${${realDirname}}/index.html\``
        args[0]['process.env'].BASE_URL = realDirname
        args[0].__static = realDirname
        return args
      })
    } else Eif (process.env.NODE_ENV === 'development') {
      //   Set __static to absolute path to public folder
      config.plugin('define').tap(args => {
        args[0].__static = JSON.stringify(api.resolve('./public'))
        return args
      })
    }
    // Apply user config
    rendererProcessChain(config)
  }
 
  Iif (process.env.NODE_ENV === 'test') {
    // Configure for mocha-webpack
    config.module
      .rule('shebang')
      .test(/\.js$/)
      .use('shebang')
      .loader('shebang-loader')
    config.externals({
      'vue-cli-plugin-electron-builder/lib/testWithSpectron':
        'require("vue-cli-plugin-electron-builder/lib/testWithSpectron")',
      'vue-cli-plugin-electron-builder':
        'require("vue-cli-plugin-electron-builder")'
    })
  }
 
  // Older generated files expect this
  process.env.VUE_APP_NODE_MODULES_PATH = false
}
// Find all the dependencies without a `main` property or with a `binary` property or set by user and add them as webpack externals
function getExternals (api, pluginOptions) {
  const nodeModulesPath = pluginOptions.nodeModulesPath || './node_modules'
  let nodeModulesPaths = []
  if (Array.isArray(nodeModulesPath)) {
    // Set to user-defined array
    nodeModulesPaths = nodeModulesPath
  } else {
    // Add path to list
    nodeModulesPaths.push(nodeModulesPath)
  }
  const userExternalsWhitelist = []
  const userExternals = (pluginOptions.externals || []).filter((d, i) => {
    // if item is prefixed with "!", remove it from list and add it to userExternalsWhitelist
    if (d.match(/^!/)) {
      userExternalsWhitelist.push(d.replace(/^!/, ''))
      return false
    }
    return true
  })
  const { dependencies } = require(api.resolve('./package.json'))
  const externalsList = Object.keys(dependencies || {}).reduce(
    (depList, dep) => {
      // Return true if we want to add a dependency to externals
      try {
        let pgkString
        for (const path of nodeModulesPaths) {
          // Check if package.json exists
          if (fs.existsSync(api.resolve(`${path}/${dep}/package.json`))) {
            // If it does, read it and break
            pgkString = fs
              .readFileSync(api.resolve(`${path}/${dep}/package.json`))
              .toString()
            break
          }
        }
        Iif (!pgkString) {
          throw new Error(`Could not find a package.json for module ${dep}`)
        }
        const pkg = JSON.parse(pgkString)
        const name = userExternals.find(name =>
          new RegExp(`^${pkg.name}(/|$)`).test(name)
        )
        const fields = ['main', 'module', 'jsnext:main', 'browser']
        if (
          // Not whitelisted
          userExternalsWhitelist.indexOf(dep) === -1 &&
          // Doesn't have main property
          (!fields.some(field => field in pkg) ||
            // Has binary property
            !!pkg.binary ||
            // Has gypfile property
            !!pkg.gypfile ||
            // Listed in user-defined externals list
            !!name)
        ) {
          // Use user-provided name if it exists, for subpaths
          depList.push(name || dep)
        }
      } catch (e) {
        console.log(e)
        depList.push(dep)
      }
      return depList
    },
    []
  )
  let externals = {}
  externalsList.forEach(d => {
    // Set external to be required during runtime
    externals[d] = `require("${d}")`
  })
  return externals
}
module.exports = { getExternals, chainWebpack }