mirror of
https://github.com/wahyd4/vuepress.git
synced 2026-08-09 05:16:23 +10:00
307 lines
7.7 KiB
JavaScript
307 lines
7.7 KiB
JavaScript
'use strict'
|
|
|
|
/**
|
|
* Module dependencies.
|
|
*/
|
|
|
|
const { fs, path, logger, env } = require('@vuepress/shared-utils')
|
|
|
|
/**
|
|
* Expose createBaseConfig method.
|
|
*/
|
|
|
|
module.exports = function createBaseConfig ({
|
|
siteConfig,
|
|
sourceDir,
|
|
outDir,
|
|
base: publicPath,
|
|
markdown,
|
|
tempPath,
|
|
cacheDirectory,
|
|
cacheIdentifier,
|
|
cliOptions: {
|
|
cache
|
|
},
|
|
pluginAPI
|
|
}, isServer) {
|
|
const Config = require('webpack-chain')
|
|
const { VueLoaderPlugin } = require('vue-loader')
|
|
const CSSExtractPlugin = require('mini-css-extract-plugin')
|
|
|
|
const isProd = process.env.NODE_ENV === 'production'
|
|
const inlineLimit = 10000
|
|
|
|
const config = new Config()
|
|
|
|
config
|
|
.mode(isProd && !env.isDebug ? 'production' : 'development')
|
|
.output
|
|
.path(outDir)
|
|
.filename(isProd ? 'assets/js/[name].[chunkhash:8].js' : 'assets/js/[name].js')
|
|
.publicPath(publicPath)
|
|
|
|
if (env.isDebug) {
|
|
config.devtool('source-map')
|
|
} else if (!isProd) {
|
|
config.devtool('cheap-module-eval-source-map')
|
|
}
|
|
|
|
const modulePaths = getModulePaths()
|
|
|
|
config.resolve
|
|
.set('symlinks', true)
|
|
.alias
|
|
.set('@source', sourceDir)
|
|
.set('@app', path.resolve(__dirname, '../app'))
|
|
.set('@temp', tempPath)
|
|
.set('@dynamic', path.resolve(tempPath, 'dynamic'))
|
|
.set('@internal', path.resolve(tempPath, 'internal'))
|
|
.end()
|
|
.extensions
|
|
.merge(['.js', '.jsx', '.vue', '.json', '.styl'])
|
|
.end()
|
|
.modules
|
|
.merge(modulePaths)
|
|
|
|
config.resolveLoader
|
|
.set('symlinks', true)
|
|
.modules
|
|
.merge(modulePaths)
|
|
|
|
config.module
|
|
.noParse(/^(vue|vue-router|vuex|vuex-router-sync)$/)
|
|
|
|
if (cache === false) {
|
|
logger.tip('Clean cache...\n')
|
|
fs.emptyDirSync(cacheDirectory)
|
|
}
|
|
|
|
cacheIdentifier += `isServer:${isServer}`
|
|
|
|
function applyVuePipeline (rule) {
|
|
rule
|
|
.use('cache-loader')
|
|
.loader('cache-loader')
|
|
.options({
|
|
cacheDirectory,
|
|
cacheIdentifier
|
|
})
|
|
|
|
rule
|
|
.use('vue-loader')
|
|
.loader('vue-loader')
|
|
.options({
|
|
compilerOptions: {
|
|
preserveWhitespace: true
|
|
},
|
|
cacheDirectory,
|
|
cacheIdentifier
|
|
})
|
|
}
|
|
|
|
const vueRule = config.module
|
|
.rule('vue')
|
|
.test(/\.vue$/)
|
|
|
|
applyVuePipeline(vueRule)
|
|
|
|
const mdRule = config.module
|
|
.rule('markdown')
|
|
.test(/\.md$/)
|
|
|
|
applyVuePipeline(mdRule)
|
|
|
|
mdRule
|
|
.use('markdown-loader')
|
|
.loader(require.resolve('@vuepress/markdown-loader'))
|
|
.options({ sourceDir, markdown })
|
|
|
|
config.module
|
|
.rule('pug')
|
|
.test(/\.pug$/)
|
|
.use('pug-plain-loader')
|
|
.loader('pug-plain-loader')
|
|
.end()
|
|
|
|
if (!siteConfig.evergreen) {
|
|
const libDir = path.join(__dirname, '..')
|
|
config.module
|
|
.rule('js')
|
|
.test(/\.js$/)
|
|
.exclude.add(filePath => {
|
|
// Always transpile lib directory
|
|
if (filePath.startsWith(libDir)) {
|
|
return false
|
|
}
|
|
// always transpile js in vue files
|
|
if (/\.vue\.js$/.test(filePath)) {
|
|
return false
|
|
}
|
|
// Don't transpile node_modules
|
|
return /node_modules/.test(filePath)
|
|
}).end()
|
|
.use('cache-loader')
|
|
.loader('cache-loader')
|
|
.options({
|
|
cacheDirectory,
|
|
cacheIdentifier
|
|
})
|
|
.end()
|
|
.use('babel-loader')
|
|
.loader('babel-loader')
|
|
.options({
|
|
// do not pick local project babel config (.babelrc)
|
|
babelrc: false,
|
|
// do not pick local project babel config (babel.config.js)
|
|
// ref: http://babeljs.io/docs/en/config-files
|
|
configFile: false,
|
|
presets: [
|
|
require.resolve('@vue/babel-preset-app')
|
|
]
|
|
})
|
|
}
|
|
|
|
config.module
|
|
.rule('images')
|
|
.test(/\.(png|jpe?g|gif)(\?.*)?$/)
|
|
.use('url-loader')
|
|
.loader('url-loader')
|
|
.options({
|
|
limit: inlineLimit,
|
|
name: `assets/img/[name].[hash:8].[ext]`
|
|
})
|
|
|
|
// do not base64-inline SVGs.
|
|
// https://github.com/facebookincubator/create-react-app/pull/1180
|
|
config.module
|
|
.rule('svg')
|
|
.test(/\.(svg)(\?.*)?$/)
|
|
.use('file-loader')
|
|
.loader('file-loader')
|
|
.options({
|
|
name: `assets/img/[name].[hash:8].[ext]`
|
|
})
|
|
|
|
config.module
|
|
.rule('media')
|
|
.test(/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/)
|
|
.use('url-loader')
|
|
.loader('url-loader')
|
|
.options({
|
|
limit: inlineLimit,
|
|
name: `assets/media/[name].[hash:8].[ext]`
|
|
})
|
|
|
|
config.module
|
|
.rule('fonts')
|
|
.test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/i)
|
|
.use('url-loader')
|
|
.loader('url-loader')
|
|
.options({
|
|
limit: inlineLimit,
|
|
name: `assets/fonts/[name].[hash:8].[ext]`
|
|
})
|
|
|
|
function createCSSRule (lang, test, loader, options) {
|
|
const baseRule = config.module.rule(lang).test(test)
|
|
const modulesRule = baseRule.oneOf('modules').resourceQuery(/module/)
|
|
const normalRule = baseRule.oneOf('normal')
|
|
|
|
applyLoaders(modulesRule, true)
|
|
applyLoaders(normalRule, false)
|
|
|
|
function applyLoaders (rule, modules) {
|
|
if (!isServer) {
|
|
if (isProd) {
|
|
rule.use('extract-css-loader').loader(CSSExtractPlugin.loader)
|
|
} else {
|
|
rule.use('vue-style-loader').loader('vue-style-loader')
|
|
}
|
|
}
|
|
|
|
rule.use('css-loader')
|
|
.loader(isServer ? 'css-loader/locals' : 'css-loader')
|
|
.options({
|
|
modules,
|
|
localIdentName: `[local]_[hash:base64:8]`,
|
|
importLoaders: 1,
|
|
sourceMap: !isProd
|
|
})
|
|
|
|
rule.use('postcss-loader').loader('postcss-loader').options(Object.assign({
|
|
plugins: [require('autoprefixer')],
|
|
sourceMap: !isProd
|
|
}, siteConfig.postcss))
|
|
|
|
if (loader) {
|
|
rule.use(loader).loader(loader).options(options)
|
|
}
|
|
}
|
|
}
|
|
|
|
createCSSRule('css', /\.css$/)
|
|
createCSSRule('postcss', /\.p(ost)?css$/)
|
|
createCSSRule('scss', /\.scss$/, 'sass-loader', siteConfig.scss)
|
|
createCSSRule('sass', /\.sass$/, 'sass-loader', Object.assign({ indentedSyntax: true }, siteConfig.sass))
|
|
createCSSRule('less', /\.less$/, 'less-loader', siteConfig.less)
|
|
createCSSRule('stylus', /\.styl(us)?$/, 'stylus-loader', Object.assign({
|
|
preferPathResolver: 'webpack'
|
|
}, siteConfig.stylus))
|
|
|
|
config
|
|
.plugin('vue-loader')
|
|
.use(VueLoaderPlugin)
|
|
|
|
if (isProd && !isServer) {
|
|
config
|
|
.plugin('extract-css')
|
|
.use(CSSExtractPlugin, [{
|
|
filename: 'assets/css/styles.[chunkhash:8].css'
|
|
}])
|
|
|
|
// ensure all css are extracted together.
|
|
// since most of the CSS will be from the theme and very little
|
|
// CSS will be from async chunks
|
|
config.optimization.splitChunks({
|
|
cacheGroups: {
|
|
styles: {
|
|
name: 'styles',
|
|
// necessary to ensure async chunks are also extracted
|
|
test: m => {
|
|
return /css\/mini-extract/.test(m.type)
|
|
},
|
|
chunks: 'all',
|
|
enforce: true
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
// inject constants
|
|
config
|
|
.plugin('injections')
|
|
.use(require('webpack/lib/DefinePlugin'), [{
|
|
VUEPRESS_VERSION: JSON.stringify(require('../../package.json').version),
|
|
VUEPRESS_TEMP_PATH: JSON.stringify(tempPath),
|
|
LAST_COMMIT_HASH: JSON.stringify(getLastCommitHash())
|
|
}])
|
|
|
|
pluginAPI.options.define.apply(config)
|
|
pluginAPI.options.alias.apply(config)
|
|
|
|
return config
|
|
}
|
|
|
|
function getLastCommitHash () {
|
|
const spawn = require('cross-spawn')
|
|
let hash
|
|
try {
|
|
hash = spawn.sync('git', ['log', '-1', '--format=%h']).stdout.toString('utf-8').trim()
|
|
} catch (error) {}
|
|
return hash
|
|
}
|
|
|
|
function getModulePaths () {
|
|
return [path.resolve(process.cwd(), 'node_modules')].concat(module.paths)
|
|
}
|