const path = require('path') const resolve = require('resolve') const { findExisting } = require('./util') module.exports = function createConfigPlugin (context, entry, asLib) { return { id: '@vue/cli-service-global-config', apply: (api, options) => { api.chainWebpack(config => { // entry is *.vue file, create alias for built-in js entry if (/\.vue$/.test(entry)) { config.resolve .alias .set('~entry', path.resolve(context, entry)) entry = require.resolve('../template/main.js') } else { // make sure entry is relative if (!/^\.\//.test(entry)) { entry = `./${entry}` } } // ensure core-js polyfills can be imported config.resolve .alias .set('core-js', path.dirname(require.resolve('core-js'))) // ensure loaders can be resolved properly // this is done by locating vue's install location (which is a // dependency of the global service) const modulePath = path.resolve(require.resolve('vue'), '../../../') config.resolveLoader .modules .add(modulePath) // add resolve alias for vue and vue-hot-reload-api // but prioritize versions installed locally. try { resolve.sync('vue', { basedir: context }) } catch (e) { const vuePath = path.dirname(require.resolve('vue')) config.resolve.alias .set('vue$', `${vuePath}/${options.compiler ? `vue.esm.js` : `vue.runtime.esm.js`}`) } try { resolve.sync('vue-hot-reload-api', { basedir: context }) } catch (e) { config.resolve.alias .set('vue-hot-reload-api', require.resolve('vue-hot-reload-api')) } // set entry config .entry('app') .clear() .add(entry) const babelOptions = { presets: [require.resolve('@vue/babel-preset-app')] } // set inline babel options config.module .rule('js') .include .clear() .end() .exclude .add(/node_modules/) .add(/@vue\/cli-service/) .end() .uses .delete('cache-loader') .end() .use('babel-loader') .tap(() => babelOptions) // check eslint config presence // otherwise eslint-loader goes all the way up to look for eslintrc, can be // messed up when the project is inside another project. const ESLintConfigFile = findExisting(context, [ '.eslintrc.js', '.eslintrc.yaml', '.eslintrc.yml', '.eslintrc.json', '.eslintrc', 'package.json' ]) const hasESLintConfig = ESLintConfigFile === 'package.json' ? !!(require(path.join(context, 'package.json')).eslintConfig) : !!ESLintConfigFile // set inline eslint options config.module .rule('eslint') .include .clear() .end() .exclude .add(/node_modules/) .end() .use('eslint-loader') .tap(options => Object.assign({}, options, { useEslintrc: hasESLintConfig, baseConfig: { extends: [ 'plugin:vue/essential', 'eslint:recommended' ] } })) if (!asLib) { // set html plugin template const indexFile = findExisting(context, [ 'index.html', 'public/index.html' ]) || path.resolve(__dirname, '../template/index.html') config .plugin('html') .tap(args => { args[0].template = indexFile return args }) } // disable copy plugin if no public dir if (asLib || !findExisting(context, ['public'])) { config.plugins.delete('copy') } }) } } }