feat: vue-loader next migration

This commit is contained in:
Clark Du 2018-03-22 17:11:16 +08:00 committed by Pooya Parsa
parent 4a5e1e1ad5
commit d35c00d729
7 changed files with 79 additions and 66 deletions

View File

@ -5,11 +5,12 @@ import TimeFixPlugin from 'time-fix-plugin'
import webpack from 'webpack' import webpack from 'webpack'
import _ from 'lodash' import _ from 'lodash'
import VueLoader from 'vue-loader'
import { isUrl, urlJoin } from '../../common/utils' import { isUrl, urlJoin } from '../../common/utils'
import customLoaders from './loaders'
import WarnFixPlugin from './plugins/warnfix' import WarnFixPlugin from './plugins/warnfix'
import ProgressPlugin from './plugins/progress' import ProgressPlugin from './plugins/progress'
import vueLoader from './vue-loader'
import styleLoaderWrapper from './style-loader' import styleLoaderWrapper from './style-loader'
/* /*
@ -68,6 +69,7 @@ export default function webpackBaseConfig({ name, isServer }) {
modules: webpackModulesDir modules: webpackModulesDir
}, },
resolveLoader: { resolveLoader: {
alias: customLoaders,
modules: webpackModulesDir modules: webpackModulesDir
}, },
module: { module: {
@ -76,7 +78,7 @@ export default function webpackBaseConfig({ name, isServer }) {
{ {
test: /\.vue$/, test: /\.vue$/,
loader: 'vue-loader', loader: 'vue-loader',
options: vueLoader.call(this, { isServer }) options: _.cloneDeep(this.options.build.vue)
}, },
{ {
test: /\.jsx?$/, test: /\.jsx?$/,
@ -123,7 +125,10 @@ export default function webpackBaseConfig({ name, isServer }) {
} }
] ]
}, },
plugins: this.options.build.plugins plugins: [
new VueLoader.VueLoaderPlugin(),
...(this.options.plugins || [])
]
} }
// Build progress indicator // Build progress indicator

View File

@ -41,7 +41,7 @@ export default function webpackClientConfig() {
config.plugins.push( config.plugins.push(
new HTMLPlugin({ new HTMLPlugin({
filename: 'index.spa.html', filename: 'index.spa.html',
template: this.options.appTemplatePath, template: 'lodash!' + this.options.appTemplatePath,
inject: true, inject: true,
chunksSortMode: 'dependency' chunksSortMode: 'dependency'
}) })
@ -52,7 +52,7 @@ export default function webpackClientConfig() {
config.plugins.push( config.plugins.push(
new HTMLPlugin({ new HTMLPlugin({
filename: 'index.ssr.html', filename: 'index.ssr.html',
template: this.options.appTemplatePath, template: 'lodash!' + this.options.appTemplatePath,
inject: false // Resources will be injected using bundleRenderer inject: false // Resources will be injected using bundleRenderer
}) })
) )

View File

@ -0,0 +1,3 @@
export default {
'lodash': require.resolve('./lodash-loader')
}

View File

@ -0,0 +1,41 @@
import _ from 'lodash'
import loaderUtils from 'loader-utils'
export default function (source) {
if (this.cacheable) {
this.cacheable()
}
// Skip .js files
if (/\.js$/.test(this.resourcePath)) {
return source
}
// The following part renders the tempalte with lodash as aminimalistic loader
//
// Get templating options
const options = this.query !== '' ? loaderUtils.parseQuery(this.query) : {}
// Webpack 2 does not allow with() statements, which lodash templates use to unwrap
// the parameters passed to the compiled template inside the scope. We therefore
// need to unwrap them ourselves here. This is essentially what lodash does internally
// To tell lodash it should not use with we set a variable
const template = _.template(source, _.defaults(options, { variable: 'data' }))
// All templateVariables which should be available
// @see HtmlWebpackPlugin.prototype.executeTemplate
const templateVariables = [
'compilation',
'webpack',
'webpackConfig',
'htmlWebpackPlugin'
]
return 'var _ = require(' + loaderUtils.stringifyRequest(this, require.resolve('lodash')) + ');' +
'module.exports = function (templateParams) {' +
// Declare the template variables in the outer scope of the
// lodash template to unwrap them
templateVariables.map(function (variableName) {
return 'var ' + variableName + ' = templateParams.' + variableName
}).join(';') + ';' +
// Execute the lodash template
'return (' + template.source + ')();' +
'}'
};

View File

@ -4,7 +4,7 @@ import MiniCssExtractPlugin from 'mini-css-extract-plugin'
import postcssConfig from './postcss' import postcssConfig from './postcss'
export default ({isVueLoader = false, isServer}) => { export default ({ isServer }) => {
return function styleLoader(ext, loaders = []) { return function styleLoader(ext, loaders = []) {
const sourceMap = Boolean(this.options.build.cssSourceMap) const sourceMap = Boolean(this.options.build.cssSourceMap)
@ -37,9 +37,7 @@ export default ({isVueLoader = false, isServer}) => {
} }
// postcss-loader // postcss-loader
// vue-loader already provides it's own
// https://github.com/postcss/postcss-loader // https://github.com/postcss/postcss-loader
if (!isVueLoader) {
const _postcssConfig = postcssConfig.call(this) const _postcssConfig = postcssConfig.call(this)
if (_postcssConfig) { if (_postcssConfig) {
@ -48,7 +46,6 @@ export default ({isVueLoader = false, isServer}) => {
options: Object.assign({ sourceMap }, _postcssConfig) options: Object.assign({ sourceMap }, _postcssConfig)
}) })
} }
}
// css-loader // css-loader
// https://github.com/webpack-contrib/css-loader // https://github.com/webpack-contrib/css-loader
@ -66,6 +63,13 @@ export default ({isVueLoader = false, isServer}) => {
} }
}) })
// Prepare vue-style-loader
// https://github.com/vuejs/vue-style-loader
loaders.unshift({
loader: 'vue-style-loader',
options: { sourceMap }
})
// -- With extractCSS -- // -- With extractCSS --
if (this.options.build.extractCSS) { if (this.options.build.extractCSS) {
if (!isServer) { if (!isServer) {
@ -79,13 +83,6 @@ export default ({isVueLoader = false, isServer}) => {
}) })
} }
} }
} else {
// Prepare vue-style-loader
// https://github.com/vuejs/vue-style-loader
loaders.unshift({
loader: 'vue-style-loader',
options: { sourceMap }
})
} }
return loaders return loaders
} }

View File

@ -1,44 +0,0 @@
import postcssConfig from './postcss'
import styleLoaderWrapper from './style-loader'
export default function vueLoader({ isServer }) {
// https://vue-loader.vuejs.org/en
const styleLoader = styleLoaderWrapper({
isServer,
isVueLoader: true
})
const config = {
postcss: postcssConfig.call(this),
cssSourceMap: this.options.build.cssSourceMap,
preserveWhitespace: false,
loaders: {
js: {
loader: 'babel-loader',
options: this.getBabelOptions({ isServer })
},
// Note: do not nest the `postcss` option under `loaders`
css: styleLoader.call(this, 'css', []),
less: styleLoader.call(this, 'less', 'less-loader'),
scss: styleLoader.call(this, 'scss', 'sass-loader'),
sass: styleLoader.call(
this,
'sass',
{ loader: 'sass-loader', options: { indentedSyntax: true } }
),
stylus: styleLoader.call(this, 'stylus', 'stylus-loader'),
styl: styleLoader.call(this, 'stylus', 'stylus-loader')
},
template: {
doctype: 'html' // For pug, see https://github.com/vuejs/vue-loader/issues/55
},
transformToRequire: {
video: 'src',
source: 'src',
object: 'src',
embed: 'src'
}
}
// Return the config
return config
}

View File

@ -59,6 +59,17 @@ export default {
babel: { babel: {
babelrc: false babelrc: false
}, },
vue: {
template: {
doctype: 'html' // For pug, see https://github.com/vuejs/vue-loader/issues/55
},
transformAssetUrls: {
video: 'src',
source: 'src',
object: 'src',
embed: 'src'
}
},
postcss: {}, postcss: {},
templates: [], templates: [],
watch: [], watch: [],