Skip to content

Commit

Permalink
fix: more global resolve fixes + better error message for missing loa…
Browse files Browse the repository at this point in the history
…ders
  • Loading branch information
yyx990803 committed Jan 26, 2018
1 parent 76dda73 commit 367b78b
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 29 deletions.
8 changes: 4 additions & 4 deletions packages/@vue/cli-plugin-babel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ module.exports = api => {
.add(api.resolve('test'))
.end()
.use('cache-loader')
.loader(require.resolve('cache-loader'))
.loader('cache-loader')
.options({ cacheDirectory })
.end()
.use('babel-loader')
.loader(require.resolve('babel-loader'))
.loader('babel-loader')

webpackConfig.module
.rule('vue')
Expand All @@ -23,11 +23,11 @@ module.exports = api => {
options.loaders = options.loaders || {}
options.loaders.js = [
{
loader: require.resolve('cache-loader'),
loader: 'cache-loader',
options: { cacheDirectory }
},
{
loader: require.resolve('babel-loader')
loader: 'babel-loader'
}
]
return options
Expand Down
2 changes: 1 addition & 1 deletion packages/@vue/cli-plugin-eslint/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module.exports = (api, { lintOnSave }) => {
.end()
.test(/\.(vue|jsx?)$/)
.use('eslint-loader')
.loader(require.resolve('eslint-loader'))
.loader('eslint-loader')
.options(Object.assign(options, {
formatter: require('eslint/lib/formatters/codeframe')
}))
Expand Down
12 changes: 6 additions & 6 deletions packages/@vue/cli-plugin-typescript/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ module.exports = (api, options) => {
// this is pending on the readiness of @babel/preset-typescript.
tsRule
.use('cache-loader')
.loader(require.resolve('cache-loader'))
.loader('cache-loader')
.options({ cacheDirectory })
.end()
.use('babel-loader')
.loader(require.resolve('babel-loader'))
.loader('babel-loader')

config.module
.rule('vue')
Expand All @@ -41,19 +41,19 @@ module.exports = (api, options) => {
if (api.hasPlugin('babel')) {
tsRule
.use('cache-loader')
.loader(require.resolve('cache-loader'))
.loader('cache-loader')
.options({ cacheDirectory })
.end()
.use('babel-loader')
.loader(require.resolve('babel-loader'))
.loader('babel-loader')
}
tsRule
.use('cache-loader-2')
.loader(require.resolve('cache-loader'))
.loader('cache-loader')
.options({ cacheDirectory })
.end()
.use('ts-loader')
.loader(require.resolve('ts-loader'))
.loader('ts-loader')
.options({
transpileOnly: true,
appendTsSuffixTo: [/\.vue$/]
Expand Down
31 changes: 20 additions & 11 deletions packages/@vue/cli-service-global/lib/createConfigPlugin.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
const path = require('path')
const resolve = require('resolve')
const { findExisting } = require('./util')

module.exports = function createConfigPlugin (context, entry) {
return {
id: '@vue/cli-service-global-config',
apply: api => {
apply: (api, options) => {
api.chainWebpack(config => {
// entry is *.vue file, create alias for built-in js entry
if (/\.vue$/.test(entry)) {
Expand All @@ -19,21 +20,29 @@ module.exports = function createConfigPlugin (context, entry) {
}
}

// include resolve for deps of this module.
// when installed globally, the location may vary depending on
// package managers their folder structures for global install.
// so we first resolve the location of vue and then trace to the
// install location.
// ensure loaders can be resolved properly
const modulePath = path.resolve(require.resolve('vue'), '../../../')

config.resolve
.modules
.add(modulePath)

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')
Expand Down
1 change: 1 addition & 0 deletions packages/@vue/cli-service-global/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@vue/cli-service": "^3.0.0-alpha.2",
"chalk": "^2.3.0",
"eslint-plugin-vue": "^4.2.0",
"resolve": "^1.5.0",
"vue": "^2.5.13"
}
}
10 changes: 5 additions & 5 deletions packages/@vue/cli-service/lib/config/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ module.exports = (api, options) => {
.rule('vue')
.test(/\.vue$/)
.use('vue-loader')
.loader(require.resolve('vue-loader'))
.loader('vue-loader')
.options(Object.assign({}, options.vueLoader))

webpackConfig.module
.rule('images')
.test(/\.(png|jpe?g|gif)(\?.*)?$/)
.use('url-loader')
.loader(require.resolve('url-loader'))
.loader('url-loader')
.options({
limit: 10000,
name: `img/[name].[hash:8].[ext]`
Expand All @@ -63,7 +63,7 @@ module.exports = (api, options) => {
.rule('svg')
.test(/\.(svg)(\?.*)?$/)
.use('file-loader')
.loader(require.resolve('file-loader'))
.loader('file-loader')
.options({
name: `img/[name].[hash:8].[ext]`
})
Expand All @@ -72,7 +72,7 @@ module.exports = (api, options) => {
.rule('media')
.test(/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/)
.use('url-loader')
.loader(require.resolve('url-loader'))
.loader('url-loader')
.options({
limit: 10000,
name: `media/[name].[hash:8].[ext]`
Expand All @@ -82,7 +82,7 @@ module.exports = (api, options) => {
.rule('fonts')
.test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/)
.use('url-loader')
.loader(require.resolve('url-loader'))
.loader('url-loader')
.options({
limit: 10000,
name: `fonts/[name].[hash:8].[ext]`
Expand Down
8 changes: 7 additions & 1 deletion packages/@vue/cli-service/lib/config/dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ module.exports = api => {
.plugin('no-emit-on-errors')
.use(require('webpack/lib/NoEmitOnErrorsPlugin'))

// friendly error plugin displays very confusing errors when webpack
// fails to resolve a loader, so we provide custom handlers to improve it
const { transformer, formatter } = require('../webpack/resolveLoaderError')
webpackConfig
.plugin('firendly-errors')
.use(require('friendly-errors-webpack-plugin'))
.use(require('friendly-errors-webpack-plugin'), [{
additionalTransformers: [transformer],
additionalFormatters: [formatter]
}])

webpackConfig
.plugin('watch-missing')
Expand Down
2 changes: 1 addition & 1 deletion packages/@vue/cli-service/lib/config/prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ module.exports = (api, options) => {
// .rule('vue')
// .use('thread-loader')
// .before('vue-loader')
// .loader(require.resolve('thread-loader'))
// .loader('thread-loader')
// .options({ name: 'vue' })
}
})
Expand Down
25 changes: 25 additions & 0 deletions packages/@vue/cli-service/lib/webpack/resolveLoaderError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const chalk = require('chalk')
const TYPE = 'cant-resolve-loader'
const errorRE = /Can't resolve '(.*loader)'/

exports.transformer = error => {
if (error.webpackError) {
const match = error.webpackError.message.match(errorRE)
if (match) {
return Object.assign({}, error, {
type: TYPE,
loader: match[1]
})
}
}
return error
}

exports.formatter = errors => {
errors = errors.filter(e => e.type === TYPE)
if (errors.length) {
return errors.map(e => {
return `Failed to resolve loader: ${chalk.yellow(e.loader)}`
}).concat(`\nYou may need to install the missing loader.`)
}
}

0 comments on commit 367b78b

Please sign in to comment.