Skip to content

Commit

Permalink
feat(generator): use style loaders only if selected
Browse files Browse the repository at this point in the history
Add generator prompts to configure the plugin to optionally load style loaders.

BREAKING CHANGE: style loaders are not automatically injected anymore

fix #20
  • Loading branch information
dnlup committed Jul 15, 2019
1 parent 230eb6c commit 79fef8a
Show file tree
Hide file tree
Showing 11 changed files with 3,477 additions and 761 deletions.
71 changes: 47 additions & 24 deletions generator/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,19 @@ function stringifyJS (value) {
}

/**
* Add a babel plugin avoiding duplicates
* @param {Array[]} plugins
* @param {Array} plugin
* Add a babel list entry avoiding duplicates
* @param {Array} list - the option list
* @param {Array} entry - the entry
* @retun {Array[]}
*/
function addBabelPlugin (plugins, plugin) {
const index = plugins.findIndex(p => p[0] === plugin[0])
function addBabeListEntry (list, entry) {
const index = list.findIndex(i => {
return Array.isArray(i) ? i[0] === entry[0] : i === entry[0]
})
if (index === -1) {
plugins.push(plugin)
list.push(entry)
}
return plugins
return list
}

/**
Expand Down Expand Up @@ -84,10 +86,10 @@ module.exports = (api, options) => {
const {
avaConfigLocation,
uiFramework,
loadStyles,
styles
} = options
const hasTS = api.hasPlugin('typescript')
const hasBabel = api.hasPlugin('babel')
const babelPluginModuleResolver = [
'module-resolver',
{
Expand All @@ -104,19 +106,35 @@ module.exports = (api, options) => {
}

if (hasTS) {
// Add Typescript configuration to ava
injectedAvaConfig.compileEnhancements = false
injectedAvaConfig.files = [
'tests/unit/**/*.spec.ts'
]
injectedAvaConfig.extensions = [
'ts'
]
} else {

// Inject Typescript dependencies
api.extendPackage({
devDependencies: {
'ts-node': injectedPackageDevDeps['ts-node'],
'tsconfig-paths': injectedPackageDevDeps['tsconfig-paths']
}
})
} else if (hasBabel) {
injectedAvaConfig.files = [
'tests/unit/**/*.spec.js'
]
} else if (!hasBabel) {
injectedAvaConfig.babel = false
injectedAvaConfig.compileEnhancements = false
injectedAvaConfig.files = [
'tests/unit/**/*.spec.js'
]
}

// Configure ava
api.render(files => {
if (avaConfigLocation === 'ava.config.js') {
const pack = JSON.parse(files['package.json'] || '{}')
Expand Down Expand Up @@ -144,7 +162,8 @@ module.exports = (api, options) => {
}
})

if (!hasTS) {
// Configure babel.config.js
if (!hasTS && hasBabel) {
api.render(files => {
let config = {}
try {
Expand All @@ -156,7 +175,16 @@ module.exports = (api, options) => {
config.env = config.env || {}
config.env.test = config.env.test || {}
config.env.test.plugins = config.env.test.plugins || []
config.env.test.plugins = addBabelPlugin(
config.env.test.presets = config.env.test.presets || []
config.env.test.presets = addBabeListEntry(config.env.test.presets, [
'@vue/app',
{
targets: {
node: 'current'
}
}
])
config.env.test.plugins = addBabeListEntry(
config.env.test.plugins,
babelPluginModuleResolver
)
Expand All @@ -172,30 +200,27 @@ module.exports = (api, options) => {
})
}

// Add Typescript dependencies
if (hasTS) {
// Add style loaders
if (styles && styles.length) {
api.extendPackage({
devDependencies: {
'ts-node': injectedPackageDevDeps['ts-node'],
'tsconfig-paths': injectedPackageDevDeps['tsconfig-paths']
'css-modules-require-hook':
injectedPackageDevDeps['css-modules-require-hook']
}
})
}

// Add UI Frameowrk specific dependencies
switch (uiFramework) {
case 'Vuetify':
if (styles.includes('stylus')) {
api.extendPackage({
devDependencies: {
stylus: injectedPackageDevDeps.stylus
}
})
}
}

api.render('./template', {
hasTS,
hasBabel,
uiFramework,
loadStyles,
styles
})

Expand All @@ -210,9 +235,7 @@ module.exports = (api, options) => {
'require-extension-hooks':
injectedPackageDevDeps['require-extension-hooks'],
'require-extension-hooks-vue':
injectedPackageDevDeps['require-extension-hooks-vue'],
'css-modules-require-hook':
injectedPackageDevDeps['css-modules-require-hook']
injectedPackageDevDeps['require-extension-hooks-vue']
},
scripts: {
'test:unit': 'vue-cli-service test:unit'
Expand Down
38 changes: 23 additions & 15 deletions generator/template/tests/helpers/setup.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
require('browser-env')()
const webpackConfig = require.resolve('@vue/cli-service/webpack.config.js')
const hooks = require('require-extension-hooks')
<%_ if (loadStyles === 'Yes' && styles.length) { _%>
<%_ if (styles && styles.length) { _%>
const css = require('css-modules-require-hook')
<%_ } _%>
<%_ if (loadStyles === 'Yes' && styles.indexOf('stylus') !== -1) { _%>
<%_ if (styles && styles.includes('stylus')) { _%>
const stylus = require('stylus')
<%_ } _%>
const Vue = require('vue')
Expand All @@ -24,6 +24,8 @@ const ts = tsNode.register({
},
transpileOnly: true
})

require('tsconfig-paths/register')
<%_ } _%>

// Fix TypeError from prettier
Expand All @@ -32,21 +34,29 @@ window.Date = Date
// Setup Vue.js to remove production tip
Vue.config.productionTip = false

<%_ if (hasTS) { _%>
// Setup vue files to be processed by `require-extension-hooks-vue`
hooks('vue').plugin('vue').push()

<%_ if (hasTS && hasBabel) { _%>
hooks('ts').push(({filename, content}) => {
content = ts.compile(content, filename)
return {
content,
filename
}
})

require('tsconfig-paths/register')

<%_ } _%>
// Setup vue files to be processed by `require-extension-hooks-vue`
hooks('vue').plugin('vue').push()
<%_ if (!hasTS) { _%>
<%_ if (hasTS && !hasBabel) { _%>
// Setup vue and ts files to be processed by `ts-node`
hooks(['vue', 'ts']).push(({filename, content}) => {
content = ts.compile(content, filename)
return {
content,
filename
}
})
<%_ } _%>
<%_ if (!hasTS && hasBabel) { _%>
// Setup vue and js files to be processed by `require-extension-hooks-babel`
hooks(['vue', 'js']).exclude(({ filename }) => {
return filename.match(/\/node_modules\//) ||
Expand All @@ -56,7 +66,7 @@ hooks(['vue', 'js']).exclude(({ filename }) => {
}).plugin('babel').push()
<%_ } _%>

<%_ if (loadStyles === 'No' || !styles.length || styles.indexOf('css') === -1) { _%>
<%_ if (!styles || !styles.length || !styles.includes('css')) { _%>
// Setup mocking of static assets
hooks([
'.css',
Expand All @@ -69,7 +79,7 @@ hooks([
'.svg'
]).push(() => '')
<%_ } _%>
<%_ if (loadStyles === 'Yes' && styles.indexOf('css') !== -1) { _%>
<%_ if (styles && styles.includes('css')) { _%>
// Setup mocking of static assets
hooks([
'.png',
Expand All @@ -80,13 +90,11 @@ hooks([
'.ico',
'.svg'
]).push(() => '')
<%_ } _%>

<%_ if (loadStyles === 'Yes' && styles.indexOf('css') !== -1) { _%>
// Setup css to be processed by `css-require-extension-hook`
css({})
<%_ } _%>
<%_ if (loadStyles === 'Yes' && styles.indexOf('stylus') !== -1) { _%>
<%_ if (styles && styles.includes('stylus')) { _%>
// Setup styl files to be processed by `css-require-extension-hook`
css({
extensions: ['.styl'],
Expand All @@ -97,7 +105,7 @@ css({
<%_ } _%>

<%_ if (uiFramework === 'Vuetify') { _%>
<%_ if (loadStyles === 'Yes' && styles.indexOf('stylus') !== -1) { _%>
<%_ if (styles && styles.includes('stylus')) { _%>
require('vuetify/src/stylus/app.styl')
<%_ } _%>
Vue.use(Vuetify, {
Expand Down
21 changes: 21 additions & 0 deletions generator/template/tests/unit/example.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<%_ if (!hasTS) { _%>
<%_ if (hasBabel) { _%>
import test from 'ava'
import { shallowMount } from '@vue/test-utils'
<%_ if (!rootOptions.bare) { _%>
Expand All @@ -17,3 +18,23 @@ test('App should render', t => {
})
<%_ } _%>
<%_ } _%>
<%_ if (!hasBabel) { _%>
const test = require('ava')
const { shallowMount } = require('@vue/test-utils')
<%_ if (!rootOptions.bare) { _%>
const HelloWorld = require('../../src/components/HelloWorld.vue')

test('HelloWorld.vue should render', t => {
const wrapper = shallowMount(HelloWorld)
t.is(wrapper.constructor.name, 'VueWrapper')
})
<%_ } else { _%>
import App from '@/App.vue'

test('App should render', t => {
const wrapper = shallowMount(App)
t.is(wrapper.constructor.name, 'VueWrapper')
})
<%_ } _%>
<%_ } _%>
<%_ } _%>
5 changes: 5 additions & 0 deletions nyc.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
exclude: [
'*tests*'
]
}
Loading

0 comments on commit 79fef8a

Please sign in to comment.