v2: prepare to move

This commit is contained in:
endiliey 2018-09-17 11:16:07 +08:00
parent dc7ef96849
commit 45736200b0
172 changed files with 0 additions and 0 deletions

133
v2/lib/webpack/base.js Normal file
View file

@ -0,0 +1,133 @@
const Config = require('webpack-chain');
const CSSExtractPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const path = require('path');
const mdLoader = require.resolve('./loader/markdown');
module.exports = function createBaseConfig(props, isServer) {
const {
siteConfig,
outDir,
themePath,
docsDir,
pagesDir,
siteDir,
sourceToMetadata,
versionedDir,
translatedDir,
baseUrl
} = props;
const config = new Config();
const isProd = process.env.NODE_ENV === 'production';
config
.mode(isProd ? 'production' : 'development')
.output.path(outDir)
.filename(isProd ? '[name].[chunkhash].js' : '[name].js')
.publicPath(isProd ? baseUrl : '/');
if (!isProd) {
config.devtool('cheap-module-eval-source-map');
}
config.resolve
.set('symlinks', true)
.alias.set('@theme', themePath)
.set('@site', siteDir)
.set('@versioned_docs', versionedDir)
.set('@translated_docs', translatedDir)
.set('@docs', docsDir)
.set('@pages', pagesDir)
.set('@build', outDir)
.set('@generated', path.resolve(__dirname, '../core/generated'))
.set('@core', path.resolve(__dirname, '../core'))
.end();
function applyBabel(rule) {
rule
.use('babel')
.loader('babel-loader')
.options({
babelrc: false,
presets: ['env', 'react'],
plugins: [isServer ? 'dynamic-import-node' : 'syntax-dynamic-import']
});
}
const jsRule = config.module
.rule('js')
.test(/\.js$/)
.exclude.add(filepath => {
// Always transpile lib directory
if (filepath.startsWith(path.join(__dirname, '..'))) {
return false;
}
// Don't transpile node_modules
return /node_modules/.test(filepath);
})
.end();
applyBabel(jsRule);
const mdRule = config.module.rule('markdown').test(/\.md$/);
applyBabel(mdRule);
mdRule
.use('markdown-loader')
.loader(mdLoader)
.options({
siteConfig,
versionedDir,
translatedDir,
docsDir,
sourceToMetadata
});
const cssRule = config.module.rule('css').test(/\.css$/);
if (!isServer) {
if (isProd) {
cssRule.use('extract-css-loader').loader(CSSExtractPlugin.loader);
} else {
cssRule.use('style-loader').loader('style-loader');
}
}
cssRule
.use('css-loader')
.loader(isServer ? 'css-loader/locals' : 'css-loader')
.options({
modules: true,
importLoaders: 1,
localIdentName: `[local]_[hash:base64:8]`,
sourceMap: !isProd,
minimize: true
});
// mini-css-extract plugin
config.plugin('extract-css').use(CSSExtractPlugin, [
{
filename: isProd ? '[name].[chunkhash].css' : '[name].css',
chunkFilename: isProd ? '[id].[chunkhash].css' : '[id].css'
}
]);
if (isProd) {
config.optimization.minimizer([
new UglifyJsPlugin({
cache: true,
uglifyOptions: {
warnings: false,
compress: false,
ecma: 6,
mangle: true
},
sourceMap: true
})
]);
}
return config;
};

30
v2/lib/webpack/client.js Normal file
View file

@ -0,0 +1,30 @@
const path = require('path');
const webpackNiceLog = require('webpack-nicelog');
const {StatsWriterPlugin} = require('webpack-stats-plugin');
const cleanWebpackPlugin = require('clean-webpack-plugin');
const createBaseConfig = require('./base');
const {applyChainWebpack} = require('./utils');
module.exports = function createClientConfig(props) {
const config = createBaseConfig(props);
config.entry('main').add(path.resolve(__dirname, '../core/clientEntry.js'));
// remove/clean build folders before building bundles
const {outDir} = props;
config
.plugin('clean')
.use(cleanWebpackPlugin, [outDir, {verbose: false, allowExternal: true}]);
// write webpack stats object so we can pickup correct client bundle path in server.
config
.plugin('stats')
.use(StatsWriterPlugin, [{filename: 'client.stats.json'}]);
// show compilation progress bar and build time
config.plugin('niceLog').use(webpackNiceLog, [{name: 'Client'}]);
// user extended webpack-chain config
applyChainWebpack(props.siteConfig.chainWebpack, config, false);
return config;
};

View file

@ -0,0 +1,78 @@
const {getOptions} = require('loader-utils');
const fm = require('front-matter');
module.exports = function(fileString) {
const options = getOptions(this);
const {
siteConfig,
versionedDir,
docsDir,
translatedDir,
sourceToMetadata
} = options;
/* Extract content of markdown (without frontmatter) */
const {body} = fm(fileString);
/* Determine the source dir. e.g: @docs, @translated_docs/ko and @versioned_docs/version-1.0.0 */
let sourceDir;
let thisSource = this.resourcePath;
if (thisSource.startsWith(translatedDir)) {
thisSource = thisSource.replace(translatedDir, '@translated_docs');
const {language, version} = sourceToMetadata[thisSource] || {};
if (language && version && version !== 'next') {
sourceDir = `@translated_docs/${language}/version-${version}`;
} else if (language && (!version || version === 'next')) {
sourceDir = `@translated_docs/${language}`;
}
} else if (thisSource.startsWith(versionedDir)) {
thisSource = thisSource.replace(versionedDir, '@versioned_docs');
const {version} = sourceToMetadata[thisSource] || {};
if (version) {
sourceDir = `@versioned_docs/version-${version}`;
}
} else if (thisSource.startsWith(docsDir)) {
sourceDir = `@docs`;
}
/* Replace internal markdown linking (except in fenced blocks) */
let content = body;
if (sourceDir) {
let fencedBlock = false;
const lines = body.split('\n').map(line => {
if (line.trim().startsWith('```')) {
fencedBlock = !fencedBlock;
}
if (fencedBlock) return line;
let modifiedLine = line;
const mdLinks = [];
const mdRegex = /(?:\]\()(?:\.\/)?([^'")\]\s>]+\.md)/g;
let match = mdRegex.exec(content);
while (match !== null) {
mdLinks.push(match[1]);
match = mdRegex.exec(content);
}
mdLinks.forEach(mdLink => {
const targetSource = `${sourceDir}/${mdLink}`;
const {permalink} = sourceToMetadata[targetSource] || {};
if (permalink) {
modifiedLine = modifiedLine.replace(mdLink, permalink);
}
});
return modifiedLine;
});
content = lines.join('\n');
}
/* Return a React component */
return (
`import React from 'react';\n` +
`import Markdown from '@theme/Markdown'\n` +
`export default () => (
<Markdown siteConfig={${JSON.stringify(siteConfig)}}>
{${JSON.stringify(content)}}
</Markdown>
);`
);
};

43
v2/lib/webpack/server.js Normal file
View file

@ -0,0 +1,43 @@
const path = require('path');
const staticSiteGenerator = require('static-site-generator-webpack-plugin');
const webpackNiceLog = require('webpack-nicelog');
const createBaseConfig = require('./base');
const {applyChainWebpack} = require('./utils');
module.exports = function createServerConfig(props) {
const config = createBaseConfig(props, true);
config.entry('main').add(path.resolve(__dirname, '../core/serverEntry.js'));
config.target('node');
config.output.filename('server.bundle.js').libraryTarget('commonjs2');
// Workaround for Webpack 4 Bug (https://github.com/webpack/webpack/issues/6522)
config.output.globalObject('this');
const {siteConfig, docsMetadatas, pagesMetadatas} = props;
// static site generator webpack plugin
const docsLinks = Object.values(docsMetadatas).map(data => ({
path: `${data.permalink}`
}));
const paths = [...docsLinks, ...pagesMetadatas].map(data => data.path);
config.plugin('siteGenerator').use(staticSiteGenerator, [
{
entry: 'main',
locals: {
baseUrl: siteConfig.baseUrl
},
paths
}
]);
// show compilation progress bar and build time
config
.plugin('niceLog')
.use(webpackNiceLog, [{name: 'Server', color: 'yellow'}]);
// user extended webpack-chain config
applyChainWebpack(props.siteConfig.chainWebpack, config, true);
return config;
};

27
v2/lib/webpack/utils.js Normal file
View file

@ -0,0 +1,27 @@
const merge = require('webpack-merge');
// Modify the generated webpack config with normal webpack config
function applyConfigureWebpack(userConfig, config, isServer) {
if (typeof userConfig === 'object') {
return merge(config, userConfig);
}
if (typeof userConfig === 'function') {
const res = userConfig(config, isServer);
if (res && typeof res === 'object') {
return merge(config, res);
}
}
return config;
}
// Modify the generated webpack config with webpack-chain API
function applyChainWebpack(userChainWebpack, config, isServer) {
if (userChainWebpack) {
userChainWebpack(config, isServer);
}
}
module.exports = {
applyConfigureWebpack,
applyChainWebpack
};