Skip to content

Commit 35d9e6f

Browse files
authored
Merge branch 'master' into typescript
2 parents 82e17e3 + 7273818 commit 35d9e6f

24 files changed

+795
-47
lines changed

fixtures/vuejs/App.vue

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<template>
2+
<div id="app">
3+
<img src="./assets/logo.png">
4+
<hello></hello>
5+
</div>
6+
</template>
7+
8+
<script>
9+
import Hello from './components/Hello'
10+
11+
class TestClassSyntax {
12+
13+
}
14+
15+
export default {
16+
name: 'app',
17+
components: {
18+
Hello
19+
}
20+
}
21+
</script>
22+
23+
<style>
24+
#app {
25+
font-family: 'Avenir', Helvetica, Arial, sans-serif;
26+
-webkit-font-smoothing: antialiased;
27+
-moz-osx-font-smoothing: grayscale;
28+
text-align: center;
29+
color: #2c3e50;
30+
margin-top: 60px;
31+
}
32+
</style>
33+
34+
<style lang="scss">
35+
#app {
36+
display: flex;
37+
color: #2c3e90;
38+
}
39+
</style>
40+
41+
<style lang="sass">
42+
#app
43+
color: #2c3e90
44+
</style>
45+
46+
<style lang="less">
47+
#app {
48+
margin-top: 40px;
49+
}
50+
</style>

fixtures/vuejs/assets/logo.png

6.69 KB
Loading

fixtures/vuejs/components/Hello.vue

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<template>
2+
<div class="hello">
3+
<h1>{{ msg }}</h1>
4+
<h2>Essential Links</h2>
5+
<ul>
6+
<li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>
7+
<li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>
8+
<li><a href="https://gitter.im/vuejs/vue" target="_blank">Gitter Chat</a></li>
9+
<li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>
10+
<br>
11+
<li><a href="http://vuejs-templates.github.io/webpack/" target="_blank">Docs for This Template</a></li>
12+
</ul>
13+
<h2>Ecosystem</h2>
14+
<ul>
15+
<li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li>
16+
<li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li>
17+
<li><a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a></li>
18+
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li>
19+
</ul>
20+
</div>
21+
</template>
22+
23+
<script>
24+
export default {
25+
name: 'hello',
26+
data () {
27+
return {
28+
msg: 'Welcome to Your Vue.js App'
29+
}
30+
}
31+
}
32+
</script>
33+
34+
<!-- Add "scoped" attribute to limit CSS to this component only -->
35+
<style scoped>
36+
h1, h2 {
37+
font-weight: normal;
38+
}
39+
40+
ul {
41+
list-style-type: none;
42+
padding: 0;
43+
}
44+
45+
li {
46+
display: inline-block;
47+
margin: 0 10px;
48+
}
49+
50+
a {
51+
color: #42b983;
52+
}
53+
</style>

fixtures/vuejs/main.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import Vue from 'vue'
2+
import App from './App'
3+
4+
new Vue({
5+
el: '#app',
6+
template: '<App/>',
7+
components: { App }
8+
})

index.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,8 @@ module.exports = {
330330
},
331331

332332
/**
333-
* If enabled, the react preset is added to Babel:
333+
* If enabled, the react preset is added to Babel.
334+
*
334335
* https://babeljs.io/docs/plugins/preset-react/
335336
*
336337
* @returns {exports}
@@ -356,6 +357,26 @@ module.exports = {
356357
*/
357358
enableTypeScriptLoader(callback) {
358359
webpackConfig.enableTypeScriptLoader(callback);
360+
}
361+
362+
/**
363+
* If enabled, the Vue.js loader is enabled.
364+
*
365+
* https://github.com/vuejs/vue-loader
366+
*
367+
* Encore.enableVueLoader();
368+
*
369+
* // or configure the vue-loader options
370+
* // https://vue-loader.vuejs.org/en/configurations/advanced.html
371+
* Encore.enableVueLoader(function(options) {
372+
* options.preLoaders = { ... }
373+
* });
374+
*
375+
* @param {function} vueLoaderOptionsCallback
376+
* @returns {exports}
377+
*/
378+
enableVueLoader(vueLoaderOptionsCallback = () => {}) {
379+
webpackConfig.enableVueLoader(vueLoaderOptionsCallback);
359380

360381
return this;
361382
},

lib/WebpackConfig.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class WebpackConfig {
5050
this.providedVariables = {};
5151
this.babelConfigurationCallback = function() {};
5252
this.useReact = false;
53+
this.useVueLoader = false;
54+
this.vueLoaderOptionsCallback = () => {};
5355
this.loaders = [];
5456
this.useTypeScriptLoader = false;
5557
this.tsConfigurationCallback = function() {};
@@ -234,6 +236,16 @@ class WebpackConfig {
234236
this.tsConfigurationCallback = callback;
235237
}
236238

239+
enableVueLoader(vueLoaderOptionsCallback = () => {}) {
240+
this.useVueLoader = true;
241+
242+
if (typeof vueLoaderOptionsCallback !== 'function') {
243+
throw new Error('Argument 1 to enableVueLoader() must be a callback function.');
244+
}
245+
246+
this.vueLoaderOptionsCallback = vueLoaderOptionsCallback;
247+
}
248+
237249
cleanupOutputBeforeBuild() {
238250
this.cleanupOutput = true;
239251
}
@@ -256,6 +268,7 @@ class WebpackConfig {
256268
this.autoProvideVariables({
257269
$: 'jquery',
258270
jQuery: 'jquery',
271+
'window.jQuery': 'jquery',
259272
});
260273
}
261274

lib/config-generator.js

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
const webpack = require('webpack');
1313
const ExtractTextPlugin = require('extract-text-webpack-plugin');
14+
const extractText = require('./loaders/extract-text');
1415
const ManifestPlugin = require('./webpack/webpack-manifest-plugin');
1516
const DeleteUnusedEntriesJSPlugin = require('./webpack/delete-unused-entries-js-plugin');
1617
const AssetOutputDisplayPlugin = require('./friendly-errors/asset-output-display-plugin');
@@ -21,12 +22,15 @@ const missingLoaderTransformer = require('./friendly-errors/transformers/missing
2122
const missingLoaderFormatter = require('./friendly-errors/formatters/missing-loader');
2223
const missingPostCssConfigTransformer = require('./friendly-errors/transformers/missing-postcss-config');
2324
const missingPostCssConfigFormatter = require('./friendly-errors/formatters/missing-postcss-config');
25+
const vueUnactivatedLoaderTransformer = require('./friendly-errors/transformers/vue-unactivated-loader-error');
26+
const vueUnactivatedLoaderFormatter = require('./friendly-errors/formatters/vue-unactivated-loader-error');
2427
const pathUtil = require('./config/path-util');
2528
const cssLoaderUtil = require('./loaders/css');
2629
const sassLoaderUtil = require('./loaders/sass');
2730
const lessLoaderUtil = require('./loaders/less');
2831
const babelLoaderUtil = require('./loaders/babel');
2932
const tsLoaderUtil = require('./loaders/typescript');
33+
const vueLoaderUtil = require('./loaders/vue');
3034

3135
class ConfigGenerator {
3236
/**
@@ -68,12 +72,15 @@ class ConfigGenerator {
6872

6973
config.stats = this.buildStatsConfig();
7074

71-
let extensions = ['.js', '.jsx', '.ts', '.tsx'];
72-
7375
config.resolve = {
74-
extensions: extensions
76+
extensions: ['.js', '.jsx', '.vue', '.ts', '.tsx'];
77+
alias: {}
7578
};
7679

80+
if (this.webpackConfig.useVueLoader) {
81+
config.resolve.alias['vue$'] = 'vue/dist/vue.esm.js';
82+
}
83+
7784
return config;
7885
}
7986

@@ -114,10 +121,7 @@ class ConfigGenerator {
114121
},
115122
{
116123
test: /\.css$/,
117-
use: ExtractTextPlugin.extract({
118-
fallback: 'style-loader' + this.getSourceMapOption(),
119-
use: cssLoaderUtil.getLoaders(this.webpackConfig)
120-
})
124+
use: extractText.extract(this.webpackConfig, cssLoaderUtil.getLoaders(this.webpackConfig, false))
121125
},
122126
{
123127
test: /\.(png|jpg|jpeg|gif|ico|svg)$/,
@@ -140,20 +144,21 @@ class ConfigGenerator {
140144
if (this.webpackConfig.useSassLoader) {
141145
rules.push({
142146
test: /\.s[ac]ss$/,
143-
use: ExtractTextPlugin.extract({
144-
fallback: 'style-loader' + this.getSourceMapOption(),
145-
use: sassLoaderUtil.getLoaders(this.webpackConfig)
146-
})
147+
use: extractText.extract(this.webpackConfig, sassLoaderUtil.getLoaders(this.webpackConfig))
147148
});
148149
}
149150

150151
if (this.webpackConfig.useLessLoader) {
151152
rules.push({
152153
test: /\.less/,
153-
use: ExtractTextPlugin.extract({
154-
fallback: 'style-loader' + this.getSourceMapOption(),
155-
use: lessLoaderUtil.getLoaders(this.webpackConfig)
156-
})
154+
use: extractText.extract(this.webpackConfig, lessLoaderUtil.getLoaders(this.webpackConfig))
155+
});
156+
}
157+
158+
if (this.webpackConfig.useVueLoader) {
159+
rules.push({
160+
test: /\.vue$/,
161+
use: vueLoaderUtil.getLoaders(this.webpackConfig, this.webpackConfig.vueLoaderOptionsCallback)
157162
});
158163
}
159164

@@ -324,11 +329,13 @@ class ConfigGenerator {
324329
clearConsole: false,
325330
additionalTransformers: [
326331
missingLoaderTransformer,
327-
missingPostCssConfigTransformer
332+
missingPostCssConfigTransformer,
333+
vueUnactivatedLoaderTransformer
328334
],
329335
additionalFormatters: [
330336
missingLoaderFormatter,
331-
missingPostCssConfigFormatter
337+
missingPostCssConfigFormatter,
338+
vueUnactivatedLoaderFormatter
332339
],
333340
compilationSuccessInfo: {
334341
messages: []
@@ -388,10 +395,6 @@ class ConfigGenerator {
388395
https: this.webpackConfig.useDevServerInHttps()
389396
};
390397
}
391-
392-
getSourceMapOption() {
393-
return this.webpackConfig.useSourceMaps ? '?sourceMap' : '';
394-
}
395398
}
396399

397400
/**
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* This file is part of the Symfony package.
3+
*
4+
* (c) Fabien Potencier <[email protected]>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
'use strict';
11+
12+
const chalk = require('chalk');
13+
14+
function formatErrors(errors) {
15+
if (errors.length === 0) {
16+
return [];
17+
}
18+
19+
let messages = [];
20+
// there will be an error for *every* file, but showing
21+
// the error over and over again is not helpful
22+
23+
messages.push(
24+
chalk.red('Vue processing failed:')
25+
);
26+
messages.push('');
27+
for (let error of errors) {
28+
messages.push(` * ${error.message}`);
29+
}
30+
31+
messages.push('');
32+
33+
return messages;
34+
}
35+
36+
function format(errors) {
37+
return formatErrors(errors.filter((e) => (
38+
e.type === 'vue-unactivated-loader-error'
39+
)));
40+
}
41+
42+
module.exports = format;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* This file is part of the Symfony package.
3+
*
4+
* (c) Fabien Potencier <[email protected]>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
'use strict';
11+
12+
const TYPE = 'vue-unactivated-loader-error';
13+
14+
function isVueUnactivatedLoaderError(e) {
15+
if (e.name !== 'ModuleBuildError') {
16+
return false;
17+
}
18+
19+
if (e.message.indexOf('Cannot process lang=') === -1) {
20+
return false;
21+
}
22+
23+
return true;
24+
}
25+
26+
function transform(error) {
27+
if (!isVueUnactivatedLoaderError(error)) {
28+
return error;
29+
}
30+
31+
error = Object.assign({}, error);
32+
33+
error.type = TYPE;
34+
error.severity = 900;
35+
36+
return error;
37+
}
38+
39+
module.exports = transform;

lib/loader-features.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ const loaderFeatures = {
4040
method: 'enableTypeScriptLoader()',
4141
packages: ['typescript', 'ts-loader'],
4242
description: 'process TypeScript files'
43+
},
44+
vue: {
45+
method: 'enableVueLoader()',
46+
// vue is needed so the end-user can do things
47+
// vue-template-compiler is a peer dep of vue-loader
48+
packages: ['vue', 'vue-loader', 'vue-template-compiler'],
49+
description: 'load VUE files'
4350
}
4451
};
4552

0 commit comments

Comments
 (0)