2018-10-31 14:05:35 -07:00
|
|
|
const hash = require('string-hash');
|
2018-09-17 13:55:49 -07:00
|
|
|
const _ = require('lodash');
|
|
|
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
|
|
|
|
|
|
const isDev = process.env.NODE_ENV === 'development';
|
|
|
|
|
|
|
|
const lessLoader = {
|
|
|
|
loader: 'less-loader',
|
|
|
|
options: { javascriptEnabled: true },
|
|
|
|
};
|
|
|
|
|
|
|
|
const tsBabelLoaderClient = {
|
|
|
|
test: /\.tsx?$/,
|
|
|
|
use: [
|
|
|
|
{
|
|
|
|
loader: 'babel-loader',
|
|
|
|
options: {
|
|
|
|
plugins: [
|
2019-01-23 12:48:22 -08:00
|
|
|
'@loadable/babel-plugin',
|
2018-09-17 13:55:49 -07:00
|
|
|
'react-hot-loader/babel',
|
|
|
|
'@babel/plugin-proposal-object-rest-spread',
|
|
|
|
'@babel/plugin-proposal-class-properties',
|
|
|
|
['import', { libraryName: 'antd', style: false }],
|
|
|
|
],
|
|
|
|
presets: ['@babel/react', ['@babel/env', { useBuiltIns: 'entry' }]],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
loader: 'ts-loader',
|
|
|
|
options: { transpileOnly: isDev },
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
|
|
|
const tsBabelLoaderServer = {
|
|
|
|
test: /\.tsx?$/,
|
|
|
|
use: [
|
|
|
|
{
|
|
|
|
loader: 'babel-loader',
|
|
|
|
options: {
|
|
|
|
plugins: [
|
2019-01-23 12:48:22 -08:00
|
|
|
'@loadable/babel-plugin',
|
2018-09-17 13:55:49 -07:00
|
|
|
'@babel/plugin-proposal-object-rest-spread',
|
|
|
|
'@babel/plugin-proposal-class-properties',
|
|
|
|
['import', { libraryName: 'antd', style: false }],
|
|
|
|
],
|
|
|
|
presets: [
|
|
|
|
'@babel/react',
|
|
|
|
['@babel/env', { useBuiltIns: 'entry', targets: { node: 'current' } }],
|
|
|
|
],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
loader: 'ts-loader',
|
|
|
|
options: { transpileOnly: isDev },
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
|
|
|
const cssLoaderClient = {
|
|
|
|
test: /\.css$/,
|
|
|
|
exclude: [/node_modules/],
|
|
|
|
use: [
|
2019-11-13 15:45:01 -08:00
|
|
|
{
|
|
|
|
loader: MiniCssExtractPlugin.loader,
|
|
|
|
options: {
|
|
|
|
hmr: isDev,
|
|
|
|
},
|
|
|
|
},
|
2018-09-17 13:55:49 -07:00
|
|
|
{
|
|
|
|
loader: 'css-loader',
|
|
|
|
},
|
2019-11-13 15:45:01 -08:00
|
|
|
]
|
2018-09-17 13:55:49 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
const lessLoaderClient = {
|
|
|
|
test: /\.less$/,
|
|
|
|
exclude: [/node_modules/],
|
|
|
|
use: [...cssLoaderClient.use, lessLoader],
|
|
|
|
};
|
|
|
|
|
|
|
|
const cssLoaderServer = {
|
|
|
|
test: /\.css$/,
|
|
|
|
exclude: [/node_modules/],
|
|
|
|
use: [
|
|
|
|
{
|
|
|
|
loader: 'css-loader/locals',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
|
|
|
const lessLoaderServer = {
|
|
|
|
test: /\.less$/,
|
|
|
|
exclude: [/node_modules/],
|
|
|
|
use: [...cssLoaderServer.use, lessLoader],
|
|
|
|
};
|
|
|
|
|
|
|
|
const urlLoaderClient = {
|
|
|
|
test: /\.(png|jpe?g|gif)$/,
|
|
|
|
loader: require.resolve('url-loader'),
|
|
|
|
options: {
|
|
|
|
limit: 2048,
|
|
|
|
name: 'assets/[name].[hash:8].[ext]',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const urlLoaderServer = {
|
|
|
|
...urlLoaderClient,
|
|
|
|
options: {
|
|
|
|
...urlLoaderClient.options,
|
|
|
|
emitFile: false,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2019-01-16 15:19:34 -08:00
|
|
|
const markdownLoaderClient = {
|
|
|
|
test: /\.md$/,
|
|
|
|
use: [
|
|
|
|
{
|
|
|
|
loader: 'html-loader',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
loader: 'markdown-loader',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
|
|
|
const markdownLoaderServer = {
|
|
|
|
...markdownLoaderClient,
|
|
|
|
use: [
|
|
|
|
{
|
|
|
|
loader: 'html-loader',
|
|
|
|
options: {
|
|
|
|
emitFile: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
loader: 'markdown-loader',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2018-09-17 13:55:49 -07:00
|
|
|
const fileLoaderClient = {
|
|
|
|
// WARNING: this will catch all files except those below
|
|
|
|
exclude: [/\.(js|ts|tsx|css|less|mjs|html|json|ejs)$/],
|
|
|
|
use: [
|
|
|
|
{
|
|
|
|
loader: 'file-loader',
|
|
|
|
options: {
|
|
|
|
name: 'assets/[name].[hash:8].[ext]',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
|
|
|
const fileLoaderServer = _.defaultsDeep(
|
|
|
|
{
|
|
|
|
use: [{ options: { emitFile: false } }],
|
|
|
|
},
|
|
|
|
fileLoaderClient,
|
|
|
|
);
|
|
|
|
|
|
|
|
const svgLoaderClient = {
|
|
|
|
test: /\.svg$/,
|
|
|
|
issuer: {
|
|
|
|
test: /\.tsx?$/,
|
|
|
|
},
|
2018-10-31 14:05:35 -07:00
|
|
|
use: ({ resource }) => ({
|
|
|
|
loader: '@svgr/webpack',
|
|
|
|
options: {
|
|
|
|
svgoConfig: {
|
2019-01-16 15:19:34 -08:00
|
|
|
plugins: [
|
|
|
|
{
|
|
|
|
inlineStyles: {
|
|
|
|
onlyMatchedOnce: false,
|
|
|
|
},
|
2018-10-31 14:05:35 -07:00
|
|
|
},
|
2019-01-16 15:19:34 -08:00
|
|
|
{
|
|
|
|
cleanupIDs: {
|
|
|
|
prefix: `svg-${hash(resource)}`,
|
|
|
|
},
|
2018-10-31 14:05:35 -07:00
|
|
|
},
|
2019-01-16 15:19:34 -08:00
|
|
|
],
|
2018-09-17 13:55:49 -07:00
|
|
|
},
|
|
|
|
},
|
2018-10-31 14:05:35 -07:00
|
|
|
}), // svg -> react component
|
2018-09-17 13:55:49 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
const svgLoaderServer = svgLoaderClient;
|
|
|
|
|
|
|
|
// Write css files from node_modules to its own vendor.css file
|
|
|
|
const externalCssLoaderClient = {
|
|
|
|
test: /\.css$/,
|
|
|
|
include: [/node_modules/],
|
|
|
|
use: [
|
2019-11-13 15:45:01 -08:00
|
|
|
MiniCssExtractPlugin.loader,
|
2018-09-17 13:55:49 -07:00
|
|
|
'css-loader',
|
2019-11-13 15:45:01 -08:00
|
|
|
]
|
2018-09-17 13:55:49 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
const externalLessLoaderClient = {
|
|
|
|
test: /\.less$/,
|
|
|
|
include: [/node_modules/],
|
|
|
|
use: [
|
2019-11-13 15:45:01 -08:00
|
|
|
MiniCssExtractPlugin.loader,
|
2018-09-17 13:55:49 -07:00
|
|
|
'css-loader',
|
|
|
|
lessLoader,
|
2019-11-13 15:45:01 -08:00
|
|
|
]
|
2018-09-17 13:55:49 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
// Server build needs a loader to handle external .css files
|
|
|
|
const externalCssLoaderServer = {
|
|
|
|
test: /\.css$/,
|
|
|
|
include: [/node_modules/],
|
|
|
|
loader: 'css-loader/locals',
|
|
|
|
};
|
|
|
|
|
|
|
|
const externalLessLoaderServer = {
|
|
|
|
test: /\.less$/,
|
|
|
|
include: [/node_modules/],
|
|
|
|
use: ['css-loader/locals', lessLoader],
|
|
|
|
};
|
|
|
|
|
|
|
|
const client = [
|
|
|
|
{
|
|
|
|
// oneOf: first matching rule takes all
|
|
|
|
oneOf: [
|
|
|
|
tsBabelLoaderClient,
|
|
|
|
cssLoaderClient,
|
|
|
|
lessLoaderClient,
|
|
|
|
svgLoaderClient,
|
|
|
|
urlLoaderClient,
|
2019-01-16 15:19:34 -08:00
|
|
|
markdownLoaderClient,
|
2018-09-17 13:55:49 -07:00
|
|
|
fileLoaderClient,
|
|
|
|
externalCssLoaderClient,
|
|
|
|
externalLessLoaderClient,
|
|
|
|
],
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const server = [
|
|
|
|
{
|
|
|
|
// oneOf: first matching rule takes all
|
|
|
|
oneOf: [
|
|
|
|
tsBabelLoaderServer,
|
|
|
|
cssLoaderServer,
|
|
|
|
lessLoaderServer,
|
|
|
|
svgLoaderServer,
|
|
|
|
urlLoaderServer,
|
2019-01-16 15:19:34 -08:00
|
|
|
markdownLoaderServer,
|
2018-09-17 13:55:49 -07:00
|
|
|
fileLoaderServer,
|
|
|
|
externalCssLoaderServer,
|
|
|
|
externalLessLoaderServer,
|
|
|
|
],
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
client,
|
|
|
|
server,
|
|
|
|
};
|