-
-
Notifications
You must be signed in to change notification settings - Fork 201
/
Copy pathmissing-loader.js
114 lines (94 loc) · 2.83 KB
/
missing-loader.js
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
/*
* This file is part of the Symfony Webpack Encore package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
'use strict';
const getVueVersion = require('../../utils/get-vue-version');
const TYPE = 'loader-not-enabled';
function isMissingLoaderError(e) {
if (e.name !== 'ModuleParseError') {
return false;
}
if (!/You may need an (appropriate|additional) loader/.test(e.message)) {
return false;
}
return true;
}
function isErrorFromVueLoader(filename) {
// vue2
if (filename.includes('??vue-loader-options')) {
return true;
}
// vue3
if (/vue-loader\/dist(\/index\.js)?\?\?/.test(filename)) {
return true;
}
// later vue3 variant
if (filename.includes('?vue') && filename.includes('lang=')) {
return true;
}
return false;
}
function getFileExtension(filename) {
// ??vue-loader-options
if (isErrorFromVueLoader(filename)) {
// vue is strange, the "filename" is reported as something like
// vue2: /path/to/project/node_modules/vue-loader/lib??vue-loader-options!./vuejs/App.vue?vue&type=style&index=1&lang=scss
// vue3: /path/to/project/node_modules/vue-loader/dist??ref--4-0!./vuejs/App.vue?vue&type=style&index=1&lang=scss
const langPos = filename.indexOf('lang=') + 5;
let endLangPos = filename.indexOf('&', langPos);
if (endLangPos === -1) {
endLangPos = filename.length;
}
return filename.substring(langPos, endLangPos);
}
const str = filename.replace(/\?.*/, '');
const split = str.split('.');
return split.pop();
}
function transform(error, webpackConfig) {
if (!isMissingLoaderError(error)) {
return error;
}
error = Object.assign({}, error);
error.isVueLoader = isErrorFromVueLoader(error.file);
const extension = getFileExtension(error.file);
switch (extension) {
case 'sass':
case 'scss':
error.loaderName = 'sass';
break;
case 'less':
error.loaderName = 'less';
break;
case 'jsx':
error.loaderName = 'react';
break;
case 'vue':
error.loaderName = 'vue' + getVueVersion(webpackConfig);
break;
case 'tsx':
case 'ts':
error.loaderName = 'typescript';
break;
// add more as needed
default:
return error;
}
error.type = TYPE;
error.severity = 900;
error.name = 'Loader not enabled';
return error;
}
/*
* Returns a factory to get the function.
*/
module.exports = function(webpackConfig) {
return function(error) {
return transform(error, webpackConfig);
};
};