UNPKG

@ytsteven/vue-cli-plugin-electron-builder

Version:
181 lines (177 loc) 6.35 kB
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) { if (pluginOptions.nodeIntegration) { // Add externals config.externals(getExternals(api, pluginOptions)) // Modify webpack config to work properly with electron config.target('electron-renderer') } config.node.set('__dirname', false).set('__filename', false) // Set IS_ELECTRON if (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].__static = realDirname return args }) } else if (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 }) const pkg = require(api.resolve('package.json')) const semver = require('semver') const electronVersion = { ...pkg.devDependencies, ...pkg.dependencies } .electron // Prefetch requests fail on Electron versions greater than 7 // https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/546 if ( /^\^?(\d|\.)*$/.test(electronVersion) && semver.gte(electronVersion.replace('^', ''), '7.0.0') ) { config.plugins.delete('prefetch') } } // Apply user config rendererProcessChain(config) } if (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, optionalDependencies } = require(api.resolve( './package.json' )) const allDependencies = Object.keys(dependencies || {}).concat( Object.keys(optionalDependencies || {}) ) const externalsList = allDependencies.reduce((depList, dep) => { try { if (process.env.VCPEB_EXPERIMENTAL_NATIVE_DEP_CHECK) { // If dep is in whitelist, don't add it no matter what if (userExternalsWhitelist.includes(dep)) { return depList } const name = userExternals.find((name) => new RegExp(`^${dep}(/|$)`).test(name) ) // If dep is listed in user external array, it is an external if (name) { // Use user-provided name if it exists to support subpaths depList.push(name || dep) return depList } for (const path of nodeModulesPaths) { // Check if binding.gyp exists if (fs.existsSync(api.resolve(`${path}/${dep}/binding.gyp`))) { // If it does, dep is native // Use user-provided name if it exists to support subpaths depList.push(name || dep) return depList } } } else { 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 } } if (!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 bin property (currently for bytenode) !!pkg.bin || // 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 }, []) const externals = {} externalsList.forEach((d) => { // Set external to be required during runtime externals[d] = `require("${d}")` }) return externals } module.exports = { getExternals, chainWebpack }