diff --git a/fixtures/vuejs-css-modules/App.vue b/fixtures/vuejs-css-modules/App.vue index 3e09beb0..b1bdc4d3 100644 --- a/fixtures/vuejs-css-modules/App.vue +++ b/fixtures/vuejs-css-modules/App.vue @@ -1,7 +1,36 @@ + + + + + + + + + + - - - - - - - - - - - \ No newline at end of file diff --git a/fixtures/vuejs-css-modules/main.js b/fixtures/vuejs-css-modules/main_v2.js similarity index 100% rename from fixtures/vuejs-css-modules/main.js rename to fixtures/vuejs-css-modules/main_v2.js diff --git a/fixtures/vuejs-css-modules/main_v3.js b/fixtures/vuejs-css-modules/main_v3.js new file mode 100644 index 00000000..258be944 --- /dev/null +++ b/fixtures/vuejs-css-modules/main_v3.js @@ -0,0 +1,4 @@ +import { createApp } from 'vue'; +import App from './App' + +createApp(App).mount('#app'); diff --git a/fixtures/vuejs-jsx/main.js b/fixtures/vuejs-jsx/main_v2.js similarity index 100% rename from fixtures/vuejs-jsx/main.js rename to fixtures/vuejs-jsx/main_v2.js diff --git a/fixtures/vuejs/main.js b/fixtures/vuejs/main_v2.js similarity index 100% rename from fixtures/vuejs/main.js rename to fixtures/vuejs/main_v2.js diff --git a/fixtures/vuejs/main_v3.js b/fixtures/vuejs/main_v3.js new file mode 100644 index 00000000..258be944 --- /dev/null +++ b/fixtures/vuejs/main_v3.js @@ -0,0 +1,4 @@ +import { createApp } from 'vue'; +import App from './App' + +createApp(App).mount('#app'); diff --git a/fixtures/vuejs-typescript/App.vue b/fixtures/vuejs2-typescript/App.vue similarity index 100% rename from fixtures/vuejs-typescript/App.vue rename to fixtures/vuejs2-typescript/App.vue diff --git a/fixtures/vuejs-typescript/assets/logo.png b/fixtures/vuejs2-typescript/assets/logo.png similarity index 100% rename from fixtures/vuejs-typescript/assets/logo.png rename to fixtures/vuejs2-typescript/assets/logo.png diff --git a/fixtures/vuejs-typescript/components/Hello.vue b/fixtures/vuejs2-typescript/components/Hello.vue similarity index 100% rename from fixtures/vuejs-typescript/components/Hello.vue rename to fixtures/vuejs2-typescript/components/Hello.vue diff --git a/fixtures/vuejs-typescript/main.ts b/fixtures/vuejs2-typescript/main.ts similarity index 100% rename from fixtures/vuejs-typescript/main.ts rename to fixtures/vuejs2-typescript/main.ts diff --git a/fixtures/vuejs-typescript/tsconfig.json b/fixtures/vuejs2-typescript/tsconfig.json similarity index 100% rename from fixtures/vuejs-typescript/tsconfig.json rename to fixtures/vuejs2-typescript/tsconfig.json diff --git a/fixtures/vuejs3-typescript/App.vue b/fixtures/vuejs3-typescript/App.vue new file mode 100644 index 00000000..f1ace5c9 --- /dev/null +++ b/fixtures/vuejs3-typescript/App.vue @@ -0,0 +1,45 @@ + + + + + + + + + diff --git a/fixtures/vuejs3-typescript/assets/logo.png b/fixtures/vuejs3-typescript/assets/logo.png new file mode 100644 index 00000000..f3d2503f Binary files /dev/null and b/fixtures/vuejs3-typescript/assets/logo.png differ diff --git a/fixtures/vuejs3-typescript/components/Hello.vue b/fixtures/vuejs3-typescript/components/Hello.vue new file mode 100644 index 00000000..7e53eaf0 --- /dev/null +++ b/fixtures/vuejs3-typescript/components/Hello.vue @@ -0,0 +1,53 @@ + + + + + + diff --git a/fixtures/vuejs3-typescript/main.ts b/fixtures/vuejs3-typescript/main.ts new file mode 100644 index 00000000..684d0421 --- /dev/null +++ b/fixtures/vuejs3-typescript/main.ts @@ -0,0 +1,4 @@ +import { createApp } from 'vue'; +import App from './App.vue'; + +createApp(App).mount('#app'); diff --git a/fixtures/vuejs3-typescript/tsconfig.json b/fixtures/vuejs3-typescript/tsconfig.json new file mode 100644 index 00000000..bb63aa7a --- /dev/null +++ b/fixtures/vuejs3-typescript/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "es6", + "strict": true, + "module": "es2015", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true + }, + "include": [ + "./**/*.ts" + ] +} \ No newline at end of file diff --git a/lib/WebpackConfig.js b/lib/WebpackConfig.js index 77f86aaf..131db1e1 100644 --- a/lib/WebpackConfig.js +++ b/lib/WebpackConfig.js @@ -136,6 +136,7 @@ class WebpackConfig { this.babelTypeScriptPresetOptions = {}; this.vueOptions = { useJsx: false, + version: null, }; this.eslintOptions = { lintVue: false, @@ -749,9 +750,21 @@ class WebpackConfig { if (!(key in this.vueOptions)) { throw new Error(`"${key}" is not a valid key for enableVueLoader(). Valid keys: ${Object.keys(this.vueOptions).join(', ')}.`); } + + if (key === 'version') { + const validVersions = [2, 3]; + if (!validVersions.includes(vueOptions.version)) { + throw new Error(`"${vueOptions.version}" is not a valid value for the "version" option passed to enableVueLoader(). Valid versions are: ${validVersions.join(', ')}.`); + } + } + + this.vueOptions[key] = vueOptions[key]; } - this.vueOptions = vueOptions; + // useJsx and vue 3 are not currently supported by Encore + if (this.vueOptions.useJsx && this.vueOptions.version === 3) { + throw new Error('Setting both "useJsx: true" and "version: 3" for enableVueLoader() is not currently supported. Please use version: 2 or disable useJsx.'); + } } enableEslintLoader(eslintLoaderOptionsOrCallback = () => {}, eslintOptions = {}) { diff --git a/lib/config-generator.js b/lib/config-generator.js index 745f0775..7ec55380 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -43,6 +43,7 @@ const PluginPriorities = require('./plugins/plugin-priorities'); const applyOptionsCallback = require('./utils/apply-options-callback'); const sharedEntryTmpName = require('./utils/sharedEntryTmpName'); const copyEntryTmpName = require('./utils/copyEntryTmpName'); +const getVueVersion = require('./utils/get-vue-version'); const tmp = require('tmp'); const fs = require('fs'); const path = require('path'); @@ -101,7 +102,10 @@ class ConfigGenerator { }; if (this.webpackConfig.useVueLoader) { - config.resolve.alias['vue$'] = 'vue/dist/vue.esm.js'; + const vueVersion = getVueVersion(this.webpackConfig); + if (vueVersion === 2) { + config.resolve.alias['vue$'] = 'vue/dist/vue.esm.js'; + } } if (this.webpackConfig.usePreact && this.webpackConfig.preactOptions.preactCompat) { diff --git a/lib/features.js b/lib/features.js index dd100af4..de02f13a 100644 --- a/lib/features.js +++ b/lib/features.js @@ -87,17 +87,28 @@ const features = { ], description: 'process TypeScript files with Babel' }, - vue: { + vue2: { method: 'enableVueLoader()', // vue is needed so the end-user can do things // vue-template-compiler is a peer dep of vue-loader packages: [ - { name: 'vue' }, - { name: 'vue-loader', enforce_version: true }, + { name: 'vue', version: '^2.5' }, + { name: 'vue-loader', version: '^15' }, { name: 'vue-template-compiler' } ], description: 'load Vue files' }, + vue3: { + method: 'enableVueLoader()', + // vue is needed so the end-user can do things + // @vue/compiler-sfc is an optional peer dep of vue-loader + packages: [ + { name: 'vue', enforce_version: true }, + { name: 'vue-loader', enforce_version: true }, + { name: '@vue/compiler-sfc' } + ], + description: 'load Vue files' + }, 'vue-jsx': { method: 'enableVueLoader()', packages: [ diff --git a/lib/friendly-errors/transformers/missing-loader.js b/lib/friendly-errors/transformers/missing-loader.js index 435849fe..f3256968 100644 --- a/lib/friendly-errors/transformers/missing-loader.js +++ b/lib/friendly-errors/transformers/missing-loader.js @@ -9,6 +9,8 @@ 'use strict'; +const getVueVersion = require('../../utils/get-vue-version'); + const TYPE = 'loader-not-enabled'; function isMissingLoaderError(e) { @@ -24,14 +26,25 @@ function isMissingLoaderError(e) { } function isErrorFromVueLoader(filename) { - return filename.includes('??vue-loader-options'); + // vue2 + if (filename.includes('??vue-loader-options')) { + return true; + } + + // vue3 + if (filename.includes('vue-loader/dist??')) { + return true; + } + + return false; } function getFileExtension(filename) { // ??vue-loader-options if (isErrorFromVueLoader(filename)) { // vue is strange, the "filename" is reported as something like - // /path/to/project/node_modules/vue-loader/lib??vue-loader-options!./vuejs/App.vue?vue&type=style&index=1&lang=scss + // 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) { @@ -47,7 +60,7 @@ function getFileExtension(filename) { return split.pop(); } -function transform(error) { +function transform(error, webpackConfig) { if (!isMissingLoaderError(error)) { return error; } @@ -68,7 +81,7 @@ function transform(error) { error.loaderName = 'react'; break; case 'vue': - error.loaderName = 'vue'; + error.loaderName = 'vue' + getVueVersion(webpackConfig); break; case 'tsx': case 'ts': @@ -86,4 +99,11 @@ function transform(error) { return error; } -module.exports = transform; +/* + * Returns a factory to get the function. + */ +module.exports = function(webpackConfig) { + return function(error) { + return transform(error, webpackConfig); + }; +}; diff --git a/lib/loaders/vue.js b/lib/loaders/vue.js index 2ac6d1fe..9a137ef3 100644 --- a/lib/loaders/vue.js +++ b/lib/loaders/vue.js @@ -12,6 +12,7 @@ const WebpackConfig = require('../WebpackConfig'); //eslint-disable-line no-unused-vars const loaderFeatures = require('../features'); const applyOptionsCallback = require('../utils/apply-options-callback'); +const getVueVersion = require('../utils/get-vue-version'); module.exports = { /** @@ -19,7 +20,8 @@ module.exports = { * @return {Array} of loaders to use for Vue files */ getLoaders(webpackConfig) { - loaderFeatures.ensurePackagesExistAndAreCorrectVersion('vue'); + const vueVersion = getVueVersion(webpackConfig); + loaderFeatures.ensurePackagesExistAndAreCorrectVersion('vue' + vueVersion); const options = {}; diff --git a/lib/package-helper.js b/lib/package-helper.js index 4c3a9540..d7bde6f4 100644 --- a/lib/package-helper.js +++ b/lib/package-helper.js @@ -67,9 +67,14 @@ function isPackageInstalled(packageConfig) { } } -function getPackageVersion(packageConfig) { +/** + * + * @param {string} packageName + * @returns {null|string} + */ +function getPackageVersion(packageName) { try { - return require(`${packageConfig.name}/package.json`).version; + return require(`${packageName}/package.json`).version; } catch (e) { return null; } @@ -135,7 +140,7 @@ function getInvalidPackageVersionRecommendations(packagesConfig) { return []; } - const version = getPackageVersion(packageConfig); + const version = getPackageVersion(packageConfig.name); // If version is null at this point it should be because // of an optional dependency whose presence has already @@ -196,4 +201,5 @@ module.exports = { getInvalidPackageVersionRecommendations, addPackagesVersionConstraint, getInstallCommand, + getPackageVersion, }; diff --git a/lib/plugins/friendly-errors.js b/lib/plugins/friendly-errors.js index 729038d0..00480ed3 100644 --- a/lib/plugins/friendly-errors.js +++ b/lib/plugins/friendly-errors.js @@ -13,7 +13,7 @@ const WebpackConfig = require('../WebpackConfig'); //eslint-disable-line no-unus const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin'); const missingCssFileTransformer = require('../friendly-errors/transformers/missing-css-file'); const missingCssFileFormatter = require('../friendly-errors/formatters/missing-css-file'); -const missingLoaderTransformer = require('../friendly-errors/transformers/missing-loader'); +const missingLoaderTransformerFactory = require('../friendly-errors/transformers/missing-loader'); const missingLoaderFormatter = require('../friendly-errors/formatters/missing-loader'); const missingPostCssConfigTransformer = require('../friendly-errors/transformers/missing-postcss-config'); const missingPostCssConfigFormatter = require('../friendly-errors/formatters/missing-postcss-config'); @@ -28,7 +28,7 @@ module.exports = function(webpackConfig) { clearConsole: false, additionalTransformers: [ missingCssFileTransformer, - missingLoaderTransformer, + missingLoaderTransformerFactory(webpackConfig), missingPostCssConfigTransformer ], additionalFormatters: [ diff --git a/lib/plugins/vue.js b/lib/plugins/vue.js index 5e1aa37c..1f264d83 100644 --- a/lib/plugins/vue.js +++ b/lib/plugins/vue.js @@ -22,7 +22,8 @@ module.exports = function(plugins, webpackConfig) { return; } - const VueLoaderPlugin = require('vue-loader/lib/plugin'); // eslint-disable-line + const { VueLoaderPlugin } = require('vue-loader'); // eslint-disable-line node/no-unpublished-require + plugins.push({ plugin: new VueLoaderPlugin(), priority: PluginPriorities.VueLoaderPlugin diff --git a/lib/utils/get-vue-version.js b/lib/utils/get-vue-version.js new file mode 100644 index 00000000..a6e4c714 --- /dev/null +++ b/lib/utils/get-vue-version.js @@ -0,0 +1,48 @@ +/* + * This file is part of the Symfony Webpack Encore package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const WebpackConfig = require('../WebpackConfig'); //eslint-disable-line no-unused-vars +const packageHelper = require('../package-helper'); +const semver = require('semver'); +const logger = require('../logger'); + +/** + * @param {WebpackConfig} webpackConfig + * @return {int|null} + */ +module.exports = function(webpackConfig) { + if (webpackConfig.vueOptions.version !== null) { + return webpackConfig.vueOptions.version; + } + + // detect installed version + const vueVersion = packageHelper.getPackageVersion('vue'); + if (null === vueVersion) { + // 2 is the current default version to recommend + return 2; + } + + if (semver.satisfies(vueVersion, '^2')) { + return 2; + } + + if (semver.satisfies(vueVersion, '^3.0.0-beta.1')) { + return 3; + } + + if (semver.satisfies(vueVersion, '^1')) { + throw new Error('vue version 1 is not supported.'); + } + + logger.warning(`Your version of vue "${vueVersion}" is newer than this version of Encore supports and may or may not function properly.`); + + return 3; +}; diff --git a/package.json b/package.json index 460c0f16..7b9c720a 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "style-loader": "^1.1.3", "terser-webpack-plugin": "^1.1.0", "tmp": "^0.2.1", - "webpack": "^4.20.0", + "webpack": "^4.22.0", "webpack-cli": "^3.0.0", "webpack-dev-server": "^3.1.14", "webpack-manifest-plugin": "^2.0.2", @@ -60,6 +60,7 @@ "@babel/preset-typescript": "^7.0.0", "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0-beta.3", "@vue/babel-preset-jsx": "^1.0.0-beta.3", + "@vue/compiler-sfc": "^3.0.0-beta.9", "autoprefixer": "^8.5.0", "babel-eslint": "^10.0.1", "chai": "^3.5.0", @@ -92,9 +93,9 @@ "ts-loader": "^5.3.0", "typescript": ">=2.9", "url-loader": "^4.0.0", - "vue": "^2.3.4", - "vue-loader": "^15.0.11", - "vue-template-compiler": "^2.3.4", + "vue": "^3.0.0-beta.9", + "vue-loader": "^16.0.0-alpha.1", + "vue-template-compiler": "^2.5.0", "webpack-notifier": "^1.6.0", "zombie": "^6.1.4" }, diff --git a/scripts/force-lowest-dependencies.js b/scripts/force-lowest-dependencies.js index 42883986..1e964c2a 100755 --- a/scripts/force-lowest-dependencies.js +++ b/scripts/force-lowest-dependencies.js @@ -12,6 +12,9 @@ const fs = require('fs'); const childProcess = require('child_process'); +const vueLowVersion = '2.5.0'; +const vueLoaderLowVersion = '15.0.11'; + function getLowestVersion(dependency, range) { return new Promise((resolve, reject) => { childProcess.exec( @@ -108,6 +111,11 @@ fs.readFile('package.json', (error, data) => { resolve(); }); })) + .then(() => { + console.log('Manually forcing Vue to version 2'); + packageInfo.devDependencies.vue = vueLowVersion; + packageInfo.devDependencies['vue-loader'] = vueLoaderLowVersion; + }) .then(() => { console.log('Updated package.json file with lowest dependency versions: '); diff --git a/test/WebpackConfig.js b/test/WebpackConfig.js index 55e3f919..885a8e5b 100644 --- a/test/WebpackConfig.js +++ b/test/WebpackConfig.js @@ -139,8 +139,10 @@ describe('WebpackConfig object', () => { it('You can omit the opening slash, but get a warning', () => { const config = createConfig(); - config.setPublicPath('foo'); + logger.reset(); + logger.quiet(); + config.setPublicPath('foo'); expect(logger.getMessages().warning).to.have.lengthOf(1); }); }); @@ -1037,7 +1039,7 @@ describe('WebpackConfig object', () => { config.enableVueLoader(() => {}, { notExisting: false, }); - }).to.throw('"notExisting" is not a valid key for enableVueLoader(). Valid keys: useJsx.'); + }).to.throw('"notExisting" is not a valid key for enableVueLoader(). Valid keys: useJsx, version.'); }); it('Should set Encore-specific options', () => { @@ -1048,8 +1050,19 @@ describe('WebpackConfig object', () => { expect(config.vueOptions).to.deep.equal({ useJsx: true, + version: null, }); }); + + it('Should validate Vue version', () => { + const config = createConfig(); + + expect(() => { + config.enableVueLoader(() => {}, { + version: 4, + }); + }).to.throw('"4" is not a valid value for the "version" option passed to enableVueLoader(). Valid versions are: 2, 3.'); + }); }); diff --git a/test/config-generator.js b/test/config-generator.js index 82375d4c..89f01bb5 100644 --- a/test/config-generator.js +++ b/test/config-generator.js @@ -479,7 +479,7 @@ describe('The config-generator function', () => { const config = createConfig(); config.outputPath = '/tmp/output/public-path'; config.publicPath = '/public-path'; - config.enableVueLoader(); // Adds the 'vue$' alias + config.enableVueLoader(() => {}, { version: 2 }); // Adds the 'vue$' alias config.enablePreactPreset({ preactCompat: true }); // Adds the 'react' and 'react-dom' aliases config.addAliases({ 'foo': 'bar', diff --git a/test/friendly-errors/transformers/missing-loader.js b/test/friendly-errors/transformers/missing-loader.js index e75a8d8f..4edd83f3 100644 --- a/test/friendly-errors/transformers/missing-loader.js +++ b/test/friendly-errors/transformers/missing-loader.js @@ -10,7 +10,14 @@ 'use strict'; const expect = require('chai').expect; -const transform = require('../../../lib/friendly-errors/transformers/missing-loader'); +const transformFactory = require('../../../lib/friendly-errors/transformers/missing-loader'); +const RuntimeConfig = require('../../../lib/config/RuntimeConfig'); +const WebpackConfig = require('../../../lib/WebpackConfig'); + +const runtimeConfig = new RuntimeConfig(); +runtimeConfig.context = __dirname; +runtimeConfig.babelRcFileExists = false; +const transform = transformFactory(new WebpackConfig(runtimeConfig)); describe('transform/missing-loader', () => { @@ -75,7 +82,7 @@ describe('transform/missing-loader', () => { expect(actualError.loaderName).to.deep.equal('typescript'); }); - it('vue-loader is handled correctly', () => { + it('vue-loader15 is handled correctly', () => { const startError = { name: 'ModuleParseError', message: 'Module parse failed: Unexpected character \'#\' (35:0)\nYou may need an appropriate loader to handle this file type.\n| \n| \n| #app {\n| display: flex;\n| color: #2c3e90;', @@ -89,6 +96,20 @@ describe('transform/missing-loader', () => { expect(actualError.isVueLoader).to.be.true; }); + it('vue-loader16 is handled correctly', () => { + const startError = { + name: 'ModuleParseError', + message: 'Module parse failed: Unexpected character \'#\' (35:0)\nYou may need an appropriate loader to handle this file type.\n| \n| \n| #app {\n| display: flex;\n| color: #2c3e90;', + file: '/path/to/project/node_modules/vue-loader/dist??ref--4-0!./vuejs/App.vue?vue&type=style&index=1&lang=scss' + }; + const actualError = transform(Object.assign({}, startError)); + + expect(actualError.name).to.deep.equal('Loader not enabled'); + expect(actualError.type).to.deep.equal('loader-not-enabled'); + expect(actualError.loaderName).to.deep.equal('sass'); + expect(actualError.isVueLoader).to.be.true; + }); + it('vue-loader is handled correctly, more options after lang=', () => { const startError = { name: 'ModuleParseError', diff --git a/test/functional.js b/test/functional.js index b94c743b..3d5dc6ce 100644 --- a/test/functional.js +++ b/test/functional.js @@ -18,6 +18,7 @@ const path = require('path'); const testSetup = require('./helpers/setup'); const fs = require('fs-extra'); const sharedEntryTmpName = require('../lib/utils/sharedEntryTmpName'); +const getVueVersion = require('../lib/utils/get-vue-version'); function createWebpackConfig(outputDirName = '', command, argv = {}) { const webpackConfig = testSetup.createWebpackConfig( @@ -938,7 +939,7 @@ describe('Functional tests using webpack', function() { config.enablePreactPreset(); config.enableSassLoader(); config.enableLessLoader(); - config.addEntry('page1', './vuejs/main'); + config.addEntry('page1', `./vuejs/main_v${getVueVersion(config)}`); config.addEntry('page2', './preact/main'); // Move Vue.js code into its own chunk @@ -1013,7 +1014,7 @@ describe('Functional tests using webpack', function() { config.enablePreactPreset(); config.enableSassLoader(); config.enableLessLoader(); - config.addEntry('page1', './vuejs/main'); + config.addEntry('page1', `./vuejs/main_v${getVueVersion(config)}`); config.addEntry('page2', './preact/main'); // Move both vue.js and preact code into their own chunk @@ -1089,7 +1090,7 @@ describe('Functional tests using webpack', function() { config.enablePreactPreset(); config.enableSassLoader(); config.enableLessLoader(); - config.addEntry('page1', './vuejs/main'); + config.addEntry('page1', `./vuejs/main_v${getVueVersion(config)}`); config.addEntry('page2', './preact/main'); // Move Vue.js code into its own chunk @@ -1120,7 +1121,7 @@ describe('Functional tests using webpack', function() { config.enablePreactPreset(); config.enableSassLoader(); config.enableLessLoader(); - config.addEntry('page1', './vuejs/main'); + config.addEntry('page1', `./vuejs/main_v${getVueVersion(config)}`); config.addEntry('page2', './preact/main'); // Move Vue.js code into its own chunk @@ -1623,7 +1624,7 @@ module.exports = { const config = testSetup.createWebpackConfig(appDir, 'www/build', 'dev'); config.enableSingleRuntimeChunk(); config.setPublicPath('/build'); - config.addEntry('main', './vuejs/main'); + config.addEntry('main', `./vuejs/main_v${getVueVersion(config)}`); config.enableVueLoader(); config.enableSassLoader(); config.enableLessLoader(); @@ -1687,7 +1688,7 @@ module.exports = { const config = testSetup.createWebpackConfig(appDir, 'www/build', 'dev'); config.enableSingleRuntimeChunk(); config.setPublicPath('/build'); - config.addEntry('main', './vuejs-typescript/main'); + config.addEntry('main', `./vuejs${getVueVersion(config)}-typescript/main`); config.enableVueLoader(); config.enableSassLoader(); config.enableLessLoader(); @@ -1741,7 +1742,7 @@ module.exports = { const config = testSetup.createWebpackConfig(appDir, 'www/build', 'dev'); config.enableSingleRuntimeChunk(); config.setPublicPath('/build'); - config.addEntry('main', './vuejs-css-modules/main'); + config.addEntry('main', `./vuejs-css-modules/main_v${getVueVersion(config)}`); config.enableVueLoader(); config.enableSassLoader(); config.enableLessLoader(); @@ -1801,17 +1802,17 @@ module.exports = { 'build/main.js' ], (browser) => { - browser.assert.hasClass('#app', 'red'); // Standard CSS - browser.assert.hasClass('#app', 'large'); // Standard SCSS - browser.assert.hasClass('#app', 'justified'); // Standard Less - browser.assert.hasClass('#app', 'lowercase'); // Standard Stylus - browser.assert.hasClass('#app', 'block'); // Standard Stylus - - browser.assert.hasClass('#app', 'italic_foo'); // CSS module - browser.assert.hasClass('#app', 'bold_foo'); // SCSS module - browser.assert.hasClass('#app', 'underline_foo'); // Less module - browser.assert.hasClass('#app', 'rtl_foo'); // Stylus module - browser.assert.hasClass('#app', 'hidden_foo'); // Stylus module + browser.assert.hasClass('#app div', 'red'); // Standard CSS + browser.assert.hasClass('#app div', 'large'); // Standard SCSS + browser.assert.hasClass('#app div', 'justified'); // Standard Less + browser.assert.hasClass('#app div', 'lowercase'); // Standard Stylus + browser.assert.hasClass('#app div', 'block'); // Standard Stylus + + browser.assert.hasClass('#app div', 'italic_foo'); // CSS module + browser.assert.hasClass('#app div', 'bold_foo'); // SCSS module + browser.assert.hasClass('#app div', 'underline_foo'); // Less module + browser.assert.hasClass('#app div', 'rtl_foo'); // Stylus module + browser.assert.hasClass('#app div', 'hidden_foo'); // Stylus module done(); } @@ -1822,7 +1823,7 @@ module.exports = { it('Vue.js error when using non-activated loaders', (done) => { const config = createWebpackConfig('www/build', 'dev'); config.setPublicPath('/build'); - config.addEntry('main', './vuejs/main'); + config.addEntry('main', `./vuejs/main_v${getVueVersion(config)}`); config.enableVueLoader(); testSetup.runWebpack(config, (webpackAssert, stats, output) => { @@ -1833,7 +1834,7 @@ module.exports = { }, true); }); - it('Vue.js is compiled correctly with JSX support', (done) => { + it('Vue.js is compiled correctly with JSX support', function(done) { const appDir = testSetup.createTestAppDir(); fs.writeFileSync( @@ -1847,9 +1848,17 @@ module.exports = { ); const config = testSetup.createWebpackConfig(appDir, 'www/build', 'dev'); + + if (getVueVersion(config) === 3) { + // not supported for vue3 at this time + this.skip(); + + return; + } + config.enableSingleRuntimeChunk(); config.setPublicPath('/build'); - config.addEntry('main', './vuejs-jsx/main'); + config.addEntry('main', `./vuejs-jsx/main_v${getVueVersion(config)}`); config.enableVueLoader(() => {}, { useJsx: true, }); @@ -2688,12 +2697,12 @@ module.exports = { webpackAssert.assertOutputJsonFileMatches('entrypoints.json', { entrypoints: { main: { - js: ['/build/runtime.js', '/build/0.js', '/build/1.js', '/build/main.js'], - css: ['/build/1.css'] + js: ['/build/runtime.js', '/build/1.js', '/build/0.js', '/build/main.js'], + css: ['/build/0.css'] }, other: { - js: ['/build/runtime.js', '/build/0.js', '/build/1.js', '/build/other.js'], - css: ['/build/1.css'] + js: ['/build/runtime.js', '/build/1.js', '/build/0.js', '/build/other.js'], + css: ['/build/0.css'] } } }); @@ -2961,10 +2970,10 @@ module.exports = { const integrityData = getIntegrityData(config); const expectedHashes = { '/build/runtime.js': 'sha384-GhoJXFTd5hHxARTOCT3RTrcOdggU7hmL/esw02KNiVIWsdumxg20TRjgdzXBMGfE', - '/build/main.js': 'sha384-TnYCkFJqLSzDkhJOQRhe1JPC6MhfAurWWjEqNVNa0YK8N4a89mMsaAHFOP+8u3Oq', + '/build/main.js': 'sha384-wkZLuTTNUxL0K7TYO/D4riciVueancehUebu/+8WGb1SANW3RnxYJTFgnhwg8Elw', '/build/main~other.js': 'sha384-XFgE9lNhD68TAYS7RjTCP7aXyjUxWftiNFMNxG7izJZ3urzp/7u1Tn4DMARxCLIw', '/build/main~other.css': 'sha384-CwxeOsagC0TZKZIMFU7gd1fQG1nbF7wHg/uLJSsU/5Soa9JwEOZcAzAFMmctn6kX', - '/build/other.js': 'sha384-xZXDGUPL+RIK36nvmtEbJleQy9BCgG89MXkrYTNcbpDcZs4C1VbWAFMFehc8Mmnw', + '/build/other.js': 'sha384-7gh0MFSndi4hHJXwmnHXUupb3TfTVCImS4idhohSOxSJ3FKKc8ybb+NxAuJbbCC3', // vendors~main~other.js's hash is not tested since its // content seems to change based on the build environment. @@ -2994,10 +3003,10 @@ module.exports = { const integrityData = getIntegrityData(config); const expectedHashes = { 'http://localhost:8090/assets/runtime.js': 'sha256-qW5QarAS9yWb4YTF5gVKNF24g4p5GayDErYme10iu7A=', - 'http://localhost:8090/assets/main.js': 'sha256-GCcvESjPed0klG3VxS0DLeRZ0UNJl/Ln210ldsAz9U4=', + 'http://localhost:8090/assets/main.js': 'sha256-3a4VzpoJ+rA8r+WhxcUcXuLS5502wUCt0cqPAHWZO5g=', 'http://localhost:8090/assets/main~other.js': 'sha256-iNXyEC346lU4Z8e4pxtatvElwLSJu/in5Mpg+EsIrwA=', 'http://localhost:8090/assets/main~other.css': 'sha256-GyGOCV1nJYunb8s/DT5wICbruabZcqzDFJRnXIlZ9I4=', - 'http://localhost:8090/assets/other.js': 'sha256-O2agOBc6WzelNGpE0dg3k6X1jtEVTRq9ogik4UAlBjg=', + 'http://localhost:8090/assets/other.js': 'sha256-9oddnaT30pExJEeYadmhuQSsYohroPuLSAnwxRX47vI=', // vendors~main~other.js's hash is not tested since its // content seems to change based on the build environment. @@ -3026,10 +3035,10 @@ module.exports = { const integrityData = getIntegrityData(config); const expectedHashes = { '/build/runtime.js': 'sha256-wxWX1GOm4edacCjvQsqZ1hG9tls4ZtuUOGQ8goGNg54= sha512-eiQrrAyaBpUlypIGVURWONjsAW8sImJllkwQ6NSDK6tIVNy/lInthruFT30x/OGRfHa4aYEaOHriEjisoxcw1Q==', - '/build/main.js': 'sha256-GCcvESjPed0klG3VxS0DLeRZ0UNJl/Ln210ldsAz9U4= sha512-dxwgdqyuVFpEn4D/xSTLDf524+OSdwBgAYwB6zRswaM4SszrrClIBK3FScktIU3CNWEqiHgjHPj2SnQTLAonGg==', + '/build/main.js': 'sha256-3a4VzpoJ+rA8r+WhxcUcXuLS5502wUCt0cqPAHWZO5g= sha512-ay7YoJiViziqmG2wUJgAbHfbXH1I27AXI1rPhBCTu5cjc+n9dvMeSmJJumtveDOP0PdqYWahtmmS2ozwRMK0lg==', '/build/main~other.js': 'sha256-iNXyEC346lU4Z8e4pxtatvElwLSJu/in5Mpg+EsIrwA= sha512-ay9A5f9PnQgqkt0obZY0UD+Bx0IVf13NijC74/Gek6Fl5JoOpHMXBlqWxZnMlnbP0/OCm1lgKRDitLd4vys87w==', '/build/main~other.css': 'sha256-bsTMZz4D7wBon35PnVm0dN51OH4EMq79NRecjZVoJ0A= sha512-kUbxtlmFlqBd+mB0P2HfsGoTZDGjdPz/BT9wc7l5fdSkML8CCNGg/ccrWXglUNIdgH10y92Jf8zIOHTRygXwxQ==', - '/build/other.js': 'sha256-O2agOBc6WzelNGpE0dg3k6X1jtEVTRq9ogik4UAlBjg= sha512-tXToyMmW0EuKUF667SlO7QJZFg8eE6fHSmZIk7G0qIo9oUhgMQzwWyc5UpzlHlTOoLaKWB+UNgjOb0x3t28PZg==', + '/build/other.js': 'sha256-9oddnaT30pExJEeYadmhuQSsYohroPuLSAnwxRX47vI= sha512-eYhSSl7Q366tIcT+pt6diNaa4a8PfLReY4skS/1GWzmbtSwKBJCArvZDSSNofm1t3V2YgzEprtcMa/Ixucn02A==', // vendors~main~other.js's hash is not tested since its // content seems to change based on the build environment. diff --git a/test/package-helper.js b/test/package-helper.js index c67fb65b..aa085385 100644 --- a/test/package-helper.js +++ b/test/package-helper.js @@ -159,13 +159,22 @@ describe('package-helper', () => { // just sass-loader expect(versionProblems).to.have.length(1); }); + + it('Beta version is ok', () => { + const versionProblems = packageHelper.getInvalidPackageVersionRecommendations([ + { name: 'vue', version: '^3.0.0-beta.5' }, + ]); + + expect(versionProblems).to.be.empty; + }); }); describe('addPackagesVersionConstraint', () => { it('Lookup a version constraint', () => { const inputPackages = [ { name: 'sass-loader', enforce_version: 7 }, - { name: 'node-sass' } + { name: 'node-sass' }, + { name: 'vue', version: '^2' } ]; const packageInfo = JSON.parse( @@ -174,7 +183,8 @@ describe('package-helper', () => { const expectedPackages = [ { name: 'sass-loader', version: packageInfo.devDependencies['sass-loader'] }, - { name: 'node-sass' } + { name: 'node-sass' }, + { name: 'vue', version: '^2' } ]; const actualPackages = packageHelper.addPackagesVersionConstraint(inputPackages); diff --git a/test/utils/get-vue-version.js b/test/utils/get-vue-version.js new file mode 100644 index 00000000..e6628dd8 --- /dev/null +++ b/test/utils/get-vue-version.js @@ -0,0 +1,83 @@ +/* + * This file is part of the Symfony Webpack Encore package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const expect = require('chai').expect; +const getVueVersion = require('../../lib/utils/get-vue-version'); +const sinon = require('sinon'); +const packageHelper = require('../../lib/package-helper'); +const WebpackConfig = require('../../lib/WebpackConfig'); +const RuntimeConfig = require('../../lib/config/RuntimeConfig'); + +const createWebpackConfig = function() { + const runtimeConfig = new RuntimeConfig(); + runtimeConfig.context = __dirname; + runtimeConfig.environment = 'dev'; + runtimeConfig.babelRcFileExists = false; + + return new WebpackConfig(runtimeConfig); +}; + +describe('get-vue-version', () => { + let getPackageVersionStub = null; + before(() => { + getPackageVersionStub = sinon.stub(packageHelper, 'getPackageVersion'); + }); + after(() => { + packageHelper.getPackageVersion.restore(); + }); + + it('returns the value configured in Webpack.config.js', () => { + const config = createWebpackConfig(); + config.vueOptions.version = 3; + + expect(getVueVersion(config)).to.equal(3); + }); + + it('returns the default recommended version when vue is not installed', () => { + const config = createWebpackConfig(); + getPackageVersionStub + .callsFake(() => null); + + expect(getVueVersion(config)).to.equal(2); + }); + + it('return 2 when Vue 2 is installed', () => { + const config = createWebpackConfig(); + getPackageVersionStub + .callsFake(() => '2.2.4'); + + expect(getVueVersion(config)).to.equal(2); + }); + + it('returns 3 when Vue 3 beta is installed', () => { + const config = createWebpackConfig(); + getPackageVersionStub + .callsFake(() => '3.0.0-beta.9'); + + expect(getVueVersion(config)).to.equal(3); + }); + + it('returns 3 when Vue 3 is installed', () => { + const config = createWebpackConfig(); + getPackageVersionStub + .callsFake(() => '3.0.0'); + + expect(getVueVersion(config)).to.equal(3); + }); + + it('returns 3 when a version is too new', () => { + const config = createWebpackConfig(); + getPackageVersionStub + .callsFake(() => '4.0.0'); // unsupported version + + expect(getVueVersion(config)).to.equal(3); + }); +}); diff --git a/yarn.lock b/yarn.lock index 8780c6d6..5994a6de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -963,21 +963,79 @@ "@vue/babel-plugin-transform-vue-jsx" "^1.1.2" camelcase "^5.0.0" -"@vue/component-compiler-utils@^3.1.0": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.1.2.tgz#8213a5ff3202f9f2137fe55370f9e8b9656081c3" - integrity sha512-QLq9z8m79mCinpaEeSURhnNCN6djxpHw0lpP/bodMlt5kALfONpryMthvnrQOlTcIKoF+VoPi+lPHUYeDFPXug== +"@vue/compiler-core@3.0.0-beta.9": + version "3.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.0.0-beta.9.tgz#4ecf5012d9fc5757337ad7bffcc9758e133c16a2" + integrity sha512-9wSyjY4n4+XySezEt8j+fe+UCht+HyqIT98lafqcZ/c7GVNNz87zej0VNR/tO1agwSdPZjApRv/kes7lcKs88w== + dependencies: + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" + "@vue/shared" "3.0.0-beta.9" + estree-walker "^0.8.1" + source-map "^0.6.1" + +"@vue/compiler-dom@3.0.0-beta.9": + version "3.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.0.0-beta.9.tgz#ef4fd5cdcdceb37d67eccb70d28d09cecf0a3425" + integrity sha512-KMWbE/O+177d8QSS46fyCYDipOw4RIoh9mo1s1CqBWQxHwNelOMU4NnHZ9TvpxBo+Dzyvzk9b9x/56KSKMcdJg== dependencies: + "@vue/compiler-core" "3.0.0-beta.9" + "@vue/shared" "3.0.0-beta.9" + +"@vue/compiler-sfc@^3.0.0-beta.9": + version "3.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.0.0-beta.9.tgz#3b85acf7c8b9792ffcfa9880cb8684fe679d25b3" + integrity sha512-J6C4l8GxP2jWRZFXGO4AwZcOzHUYNT08kGTFZM2V9GBMg3UaLmE6DvUPTPBTrBL55RTyaV2O+U44S5iYlyUi1A== + dependencies: + "@vue/compiler-core" "3.0.0-beta.9" + "@vue/compiler-dom" "3.0.0-beta.9" + "@vue/compiler-ssr" "3.0.0-beta.9" + "@vue/shared" "3.0.0-beta.9" consolidate "^0.15.1" - hash-sum "^1.0.2" - lru-cache "^4.1.2" + hash-sum "^2.0.0" + lru-cache "^5.1.1" merge-source-map "^1.1.0" - postcss "^7.0.14" + postcss "^7.0.27" + postcss-modules "^2.0.0" postcss-selector-parser "^6.0.2" - source-map "~0.6.1" - vue-template-es2015-compiler "^1.9.0" - optionalDependencies: - prettier "^1.18.2" + source-map "^0.6.1" + +"@vue/compiler-ssr@3.0.0-beta.9": + version "3.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.0.0-beta.9.tgz#be8fd55885218957a65a333f129783c36a882657" + integrity sha512-WoOd36XPR5aY9es+pTuP0DVPY45sDQnXBxFDagNUOJ3VXu40NLwiXYNTRxRPOExkgEL0YcDNds6/bLqDWGD4JQ== + dependencies: + "@vue/compiler-dom" "3.0.0-beta.9" + "@vue/shared" "3.0.0-beta.9" + +"@vue/reactivity@3.0.0-beta.9": + version "3.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.0.0-beta.9.tgz#3a81a6a0dff47ee4713aceb5c77302620de471fe" + integrity sha512-cdAwMceme0ku8M/9npFx2jHMJexlOctA8bJA5LNF8ISaQcfklTGa2u7+iWZDfF6slxPjkeGKLpOyKE5qIdBgAA== + dependencies: + "@vue/shared" "3.0.0-beta.9" + +"@vue/runtime-core@3.0.0-beta.9": + version "3.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.0.0-beta.9.tgz#7b9ab834e0a566ec669e463b301bad327a95a6dc" + integrity sha512-SU8OFkgnRoWQNEdHqPqubIKrTWwR3f68SRxdyOvre2NoPPCf6+TWoNlrWMBFSROn0qvhFOvQybJt3002uD0uQw== + dependencies: + "@vue/reactivity" "3.0.0-beta.9" + "@vue/shared" "3.0.0-beta.9" + +"@vue/runtime-dom@3.0.0-beta.9": + version "3.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.0.0-beta.9.tgz#cebfa7f9e417e0502bbb37b40b8fdc089fe70100" + integrity sha512-P0IUIShcudwEZ0ez1nQXyKY0hzrHfwxmz1b+z7ppeoVIDf3tKSwL1gCqPtQdYwWyfu8bTU8C/8DQF3V7jcyeZA== + dependencies: + "@vue/runtime-core" "3.0.0-beta.9" + "@vue/shared" "3.0.0-beta.9" + csstype "^2.6.8" + +"@vue/shared@3.0.0-beta.9": + version "3.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.0-beta.9.tgz#b3bfd0553bef22d508d0e56cc305e25783e64017" + integrity sha512-ndn3/TCCzvmFI5zTpBTdKdNW2x+ibshvjcoajvcUXNRLlHVJNad0PdnvklPu6zaI6+9fkFpFC5AnMkLg5/KvSw== "@webassemblyjs/ast@1.9.0": version "1.9.0" @@ -2504,6 +2562,18 @@ css-loader@^3.5.2: schema-utils "^2.6.6" semver "^6.3.0" +css-modules-loader-core@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz#5908668294a1becd261ae0a4ce21b0b551f21d16" + integrity sha1-WQhmgpShvs0mGuCkziGwtVHyHRY= + dependencies: + icss-replace-symbols "1.1.0" + postcss "6.0.1" + postcss-modules-extract-imports "1.1.0" + postcss-modules-local-by-default "1.2.0" + postcss-modules-scope "1.1.0" + postcss-modules-values "1.3.0" + css-parse@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-2.0.0.tgz#a468ee667c16d81ccf05c58c38d2a97c780dbfd4" @@ -2536,6 +2606,15 @@ css-select@^2.0.0: domutils "^1.7.0" nth-check "^1.0.2" +css-selector-tokenizer@^0.7.0: + version "0.7.2" + resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.2.tgz#11e5e27c9a48d90284f22d45061c303d7a25ad87" + integrity sha512-yj856NGuAymN6r8bn8/Jl46pR+OC3eEvAhfGYDUe7YPtTPAYrSSw4oAniZ9Y8T5B92hjhwTBLUen0/vKPxf6pw== + dependencies: + cssesc "^3.0.0" + fastparse "^1.1.2" + regexpu-core "^4.6.0" + css-tree@1.0.0-alpha.37: version "1.0.0-alpha.37" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" @@ -2664,6 +2743,11 @@ cssstyle@^1.0.0: dependencies: cssom "0.3.x" +csstype@^2.6.8: + version "2.6.10" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.10.tgz#e63af50e66d7c266edb6b32909cfd0aabe03928b" + integrity sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w== + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -3366,6 +3450,11 @@ estraverse@^5.1.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.1.0.tgz#374309d39fd935ae500e7b92e8a6b4c720e59642" integrity sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw== +estree-walker@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.8.1.tgz#6230ce2ec9a5cb03888afcaf295f97d90aa52b79" + integrity sha512-H6cJORkqvrNziu0KX2hqOMAlA2CiuAxHeGJXSIoKA/KLv229Dw806J3II6mKTm5xiDX1At1EXCfsOQPB+tMB+g== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -3545,7 +3634,7 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -fastparse@^1.0.0: +fastparse@^1.0.0, fastparse@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== @@ -3884,6 +3973,13 @@ gaze@^1.0.0: dependencies: globule "^1.0.0" +generic-names@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/generic-names/-/generic-names-2.0.1.tgz#f8a378ead2ccaa7a34f0317b05554832ae41b872" + integrity sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ== + dependencies: + loader-utils "^1.1.0" + gensync@^1.0.0-beta.1: version "1.0.0-beta.1" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" @@ -4097,6 +4193,11 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -4164,10 +4265,10 @@ hash-base@^3.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" -hash-sum@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" - integrity sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ= +hash-sum@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" + integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" @@ -4360,6 +4461,11 @@ iconv-lite@0.4.24, iconv-lite@^0.4.21, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +icss-replace-symbols@1.1.0, icss-replace-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= + icss-utils@^4.0.0, icss-utils@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" @@ -5183,6 +5289,11 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" @@ -5245,7 +5356,7 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" -lru-cache@^4.0.1, lru-cache@^4.1.2: +lru-cache@^4.0.1: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== @@ -6449,6 +6560,13 @@ postcss-minify-selectors@^4.0.2: postcss "^7.0.0" postcss-selector-parser "^3.0.0" +postcss-modules-extract-imports@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz#b614c9720be6816eaee35fb3a5faa1dba6a05ddb" + integrity sha1-thTJcgvmgW6u41+zpfqh26agXds= + dependencies: + postcss "^6.0.1" + postcss-modules-extract-imports@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" @@ -6456,6 +6574,14 @@ postcss-modules-extract-imports@^2.0.0: dependencies: postcss "^7.0.5" +postcss-modules-local-by-default@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" + integrity sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk= + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" + postcss-modules-local-by-default@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915" @@ -6466,6 +6592,14 @@ postcss-modules-local-by-default@^3.0.2: postcss-selector-parser "^6.0.2" postcss-value-parser "^4.0.0" +postcss-modules-scope@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" + integrity sha1-1upkmUx5+XtipytCb75gVqGUu5A= + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" + postcss-modules-scope@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" @@ -6474,6 +6608,14 @@ postcss-modules-scope@^2.2.0: postcss "^7.0.6" postcss-selector-parser "^6.0.0" +postcss-modules-values@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" + integrity sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA= + dependencies: + icss-replace-symbols "^1.1.0" + postcss "^6.0.1" + postcss-modules-values@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" @@ -6482,6 +6624,17 @@ postcss-modules-values@^3.0.0: icss-utils "^4.0.0" postcss "^7.0.6" +postcss-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules/-/postcss-modules-2.0.0.tgz#473d0d7326651d8408585c2a154115d5cb36cce0" + integrity sha512-eqp+Bva+U2cwQO7dECJ8/V+X+uH1HduNeITB0CPPFAu6d/8LKQ32/j+p9rQ2YL1QytVcrNU0X+fBqgGmQIA1Rw== + dependencies: + css-modules-loader-core "^1.1.0" + generic-names "^2.0.1" + lodash.camelcase "^4.3.0" + postcss "^7.0.1" + string-hash "^1.1.1" + postcss-normalize-charset@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" @@ -6639,6 +6792,15 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^ resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== +postcss@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.1.tgz#000dbd1f8eef217aa368b9a212c5fc40b2a8f3f2" + integrity sha1-AA29H47vIXqjaLmiEsX8QLKo8/I= + dependencies: + chalk "^1.1.3" + source-map "^0.5.6" + supports-color "^3.2.3" + postcss@7.0.21: version "7.0.21" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.21.tgz#06bb07824c19c2021c5d056d5b10c35b989f7e17" @@ -6648,7 +6810,7 @@ postcss@7.0.21: source-map "^0.6.1" supports-color "^6.1.0" -postcss@^6.0.23: +postcss@^6.0.1, postcss@^6.0.23: version "6.0.23" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== @@ -6705,11 +6867,6 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prettier@^1.18.2: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== - pretty-error@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" @@ -7059,7 +7216,7 @@ regexpp@^2.0.1: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== -regexpu-core@^4.7.0: +regexpu-core@^4.6.0, regexpu-core@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== @@ -7847,6 +8004,11 @@ stream-shift@^1.0.0: resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== +string-hash@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" + integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs= + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -8051,6 +8213,13 @@ supports-color@^2.0.0: resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= +supports-color@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + supports-color@^5.3.0, supports-color@^5.4.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -8600,31 +8769,18 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -vue-hot-reload-api@^2.3.0: - version "2.3.4" - resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2" - integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog== - -vue-loader@^15.0.11: - version "15.9.2" - resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.9.2.tgz#ae01f5f4c9c6a04bff4483912e72ef91a402c1ae" - integrity sha512-oXBubaY//CYEISBlHX+c2YPJbmOH68xXPXjFv4MAgPqQvUsnjrBAjCJi8HXZ/r/yfn0tPL5VZj1Zcp8mJPI8VA== +vue-loader@^16.0.0-alpha.1: + version "16.0.0-alpha.3" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-16.0.0-alpha.3.tgz#3471a3325a07a94e569aa281f83361819e4ad280" + integrity sha512-aC7TyXfzGs30mgru4iSfmEC8ZQigwpetaBpr/Q0PA0DZa5lEX9NMT7py9SCrXVq7mZeaYaz0QC/kzuUZtnYMHw== dependencies: - "@vue/component-compiler-utils" "^3.1.0" - hash-sum "^1.0.2" - loader-utils "^1.1.0" - vue-hot-reload-api "^2.3.0" - vue-style-loader "^4.1.0" - -vue-style-loader@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.2.tgz#dedf349806f25ceb4e64f3ad7c0a44fba735fcf8" - integrity sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ== - dependencies: - hash-sum "^1.0.2" - loader-utils "^1.0.2" + chalk "^3.0.0" + hash-sum "^2.0.0" + loader-utils "^1.2.3" + merge-source-map "^1.1.0" + source-map "^0.6.1" -vue-template-compiler@^2.3.4: +vue-template-compiler@^2.5.0: version "2.6.11" resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080" integrity sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA== @@ -8632,15 +8788,14 @@ vue-template-compiler@^2.3.4: de-indent "^1.0.2" he "^1.1.0" -vue-template-es2015-compiler@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" - integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw== - -vue@^2.3.4: - version "2.6.11" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5" - integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ== +vue@^3.0.0-beta.9: + version "3.0.0-beta.9" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.0-beta.9.tgz#f2cfcf5bafa8da9fb8b4fc8249f06674a38ed19f" + integrity sha512-K9EBlcTSRDIXo8IkRK5fY1X4cU6Z7iE7F6wSyMyzWWfuJCg1uO+xPEmRfp+kSioRk2QOtAJOqADpNsR+dM4bmQ== + dependencies: + "@vue/compiler-dom" "3.0.0-beta.9" + "@vue/runtime-dom" "3.0.0-beta.9" + "@vue/shared" "3.0.0-beta.9" w3c-hr-time@^1.0.1: version "1.0.2" @@ -8772,7 +8927,7 @@ webpack-sources@^1.1.0, webpack-sources@^1.3.0, webpack-sources@^1.4.0, webpack- source-list-map "^2.0.0" source-map "~0.6.1" -webpack@^4.20.0: +webpack@^4.22.0: version "4.43.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.43.0.tgz#c48547b11d563224c561dad1172c8aa0b8a678e6" integrity sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==