ecology9-src4js-tools
Version:
src4js-tools
425 lines (391 loc) • 14.1 kB
JavaScript
const { injectBabelPlugin, getLoader ,paths } = require('./config/react-app-rewired');
const webpack = require('webpack');
const path = require('path');
const fs = require('fs');
// const url = require('url');
const argv = require('yargs').argv;
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin'); // 用于替换 SWPrecacheWebpackPlugin
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackHandleCssInjectPlugin = require('./config/webpack-theme-plugin');
const styleLoaders = [{ loader: require.resolve('css-loader'), options: {
importLoaders: 1,
minimize: true,
sourceMap: true,
} }, { loader: require.resolve('less-loader'), }];
const resolveToThemeStaticPath = fileName => path.resolve(paths.appThemePath, fileName);
const themeFileNameSet = fs.readdirSync(path.resolve(paths.appThemePath));
const themePaths = themeFileNameSet.map(resolveToThemeStaticPath);
const getThemeName = fileName => `${path.basename(fileName, path.extname(fileName))}`;
const themesExtractLessSet = themeFileNameSet.map(fileName =>
new ExtractTextPlugin({
filename:`static/css/${getThemeName(fileName)}.css?v=[contenthash:8]`,
allChunks:true
}));
const themeLoaderSet = themeFileNameSet.map((fileName, index) => {
// console.log("fileName dd:",fileName," i:",index," resolveToThemeStaticPath(fileName):",resolveToThemeStaticPath(fileName));
return {
test: /\.(less|css)$/,
include: resolveToThemeStaticPath(fileName),
loader: themesExtractLessSet[index].extract({
use: styleLoaders
})
}
});
const lessToJs = require('less-vars-to-js');
const wmThemeDefaultPath = resolveApp('node_modules/weaver-mobile/lib/style/themes/default.less');
const wmThemeDefaulPaletteLess = fs.readFileSync(wmThemeDefaultPath, 'utf8');
const themelessVarsToJsDefault = lessToJs(wmThemeDefaulPaletteLess, {resolveVariables: true, stripPrefix: true});
const themelessVarsToJs = {};
themeFileNameSet.forEach(fileName => {
const paletteLess = fs.readFileSync(resolveToThemeStaticPath(fileName), 'utf8');
const originLess = Object.assign({}, themelessVarsToJsDefault, lessToJs(paletteLess, {resolveVariables: true, stripPrefix: true}));
const result = { hd: eval(originLess.hd.replace('px','')) };
Object.keys(originLess).forEach(l => {
const reg = /\s\*\s@hd$/;
if (originLess[l].match(reg)) {
result[l] = eval(`${originLess[l].replace(reg, '')}*${result.hd}`);
}
})
themelessVarsToJs[getThemeName(fileName)] = Object.assign({}, result, { less: originLess });
});
const fileLoaderMatcher = function (rule) {
return rule.loader && rule.loader.indexOf(`file-loader`) != -1;
}
module.exports = function override(config, env) {
if(env==='production') {
// console.log(config.plugins[config.plugins.length-1]);
// console.log(config.entry);
// config.entry = [require.resolve('./polyfills'), config.entry[1]];
config.entry = {
pre: [
require.resolve('./polyfills'),
'react',
'react-dom',
'mobx',
'mobx-react',
require.resolve('./pre.js'),
],
main: config.entry[1],
dev: require.resolve('./devComponent.js'),
};
var n = config.plugins.length;
config.plugins[n] =
new HtmlWebpackHandleCssInjectPlugin({
themelessVarsToJs,
paths,
filter: (filePath) => {
return filePath.includes('theme');
}
});
themesExtractLessSet.map((obj,i)=>{
config.plugins[n+(i+1)] = obj;
});
config.module.rules[1].oneOf.unshift(
{
test: /\.less$/,
exclude:paths.appThemePath,
loader: ExtractTextPlugin.extract(
Object.assign(
{
fallback: {
loader: require.resolve('style-loader'),
options: {
hmr: false,
},
},
use:styleLoaders
}
)
)
}
);
// css-modules
config.module.rules[1].oneOf.unshift(
{
test: /\.css$/,
exclude:paths.appThemePath,
loader: ExtractTextPlugin.extract(
Object.assign(
{
fallback: {
loader: require.resolve('style-loader'),
options: {
hmr: false,
},
},
use: styleLoaders
}
)
),
}
);
themeLoaderSet.map((obj)=>{
config.module.rules[1].oneOf.unshift(obj);
});
// config.output.filename = 'static/js/main.js?v=[hash:8]';
config.output.filename = 'static/js/[name].js?v=[hash:8]';
config.output.chunkFilename = 'static/js/[name].chunk.js?v=[chunkhash:8]';
config.plugins[4] = new ExtractTextPlugin({
filename: 'static/css/[name].css?v=[contenthash:8]',
});
if (argv.analyzer === 'true') {
config.plugins.push(new BundleAnalyzerPlugin());
}
config.plugins.push(
new webpack.optimize.CommonsChunkPlugin({
name : 'pre',
filename : 'static/js/[name].js?v=[hash:8]',
})
);
}
else {
config.module.rules[1].oneOf.unshift(
{
test: /\.less$/,
use: [
require.resolve('style-loader'),
require.resolve('css-loader'),
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
{
loader: require.resolve('less-loader'),
options: {
// theme vars, also can use theme.js instead of this.
// modifyVars: { "@brand-primary": "#1DA57A" },
},
},
]
}
);
// css-modules
config.module.rules[1].oneOf.unshift(
{
test: /\.css$/,
exclude: /node_modules|weaver-mobile\.css/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
modules: true,
importLoaders: 1,
localIdentName: '[local]___[hash:base64:5]'
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
]
}
);
config.plugins.push(
new HtmlWebpackHandleCssInjectPlugin({
isDev: true,
themelessVarsToJs,
filter: (filePath) => {
return filePath.includes('theme');
}
})
);
}
config.module.rules[1].oneOf.unshift({
test: /\.(js|jsx)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
exclude: /node_modules(\/|\\)(?!weaver-mobile-page)/,
options: {
// @remove-on-eject-begin
babelrc: false,
plugins:[
[require.resolve('babel-plugin-transform-runtime')],
[require.resolve('babel-plugin-transform-decorators-legacy')],
[require.resolve('babel-plugin-import'), [{
libraryName: 'weaver-mobile',
//style: 'css',
// style: true, // use less for customized theme
}, {
libraryName: 'weaver-mobile-page',
libraryDirectory: 'es',
//style: 'css',
// style: true, // use less for customized theme
}]],
],
presets: [
require.resolve('babel-preset-es2015'),
require.resolve('babel-preset-stage-0'),
require.resolve('babel-preset-react')
], //require.resolve('babel-preset-react-app'),
// @remove-on-eject-end
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
},
});
config.module.rules[1].oneOf.unshift({
test: /\.(js|jsx)$/,
include: /(pre|registerServiceWorker).js/,
loader: require.resolve('babel-loader'),
exclude: /node_modules(\/|\\)(?!weaver-mobile-page)/,
options: {
// @remove-on-eject-begin
babelrc: false,
plugins:[
[require.resolve('babel-plugin-transform-runtime')],
[require.resolve('babel-plugin-transform-decorators-legacy')],
[require.resolve('babel-plugin-import'), [{
libraryName: 'weaver-mobile',
//style: 'css',
// style: true, // use less for customized theme
}, {
libraryName: 'weaver-mobile-page',
libraryDirectory: 'es',
//style: 'css',
// style: true, // use less for customized theme
}]],
],
presets: [
require.resolve('babel-preset-es2015'),
require.resolve('babel-preset-stage-0'),
require.resolve('babel-preset-react')
], //require.resolve('babel-preset-react-app'),
// @remove-on-eject-end
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
},
});
config.module.rules[1].oneOf.unshift({
test: /\.(js|jsx)$/,
include: /devComponent.js/,
loader: require.resolve('babel-loader'),
exclude: /node_modules(\/|\\)(?!weaver-mobile-page)/,
options: {
// @remove-on-eject-begin
babelrc: false,
plugins:[
[require.resolve('babel-plugin-transform-runtime')],
[require.resolve('babel-plugin-transform-decorators-legacy')],
[require.resolve('babel-plugin-import'), [{
libraryName: 'weaver-mobile',
//style: 'css',
// style: true, // use less for customized theme
}, {
libraryName: 'weaver-mobile-page',
libraryDirectory: 'es',
//style: 'css',
// style: true, // use less for customized theme
}]],
],
presets: [
require.resolve('babel-preset-es2015'),
require.resolve('babel-preset-stage-0'),
require.resolve('babel-preset-react')
], //require.resolve('babel-preset-react-app'),
// @remove-on-eject-end
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
},
});
config.module.rules[1].oneOf.unshift({
test: /\.(js|jsx)$/,
include: /node_modules(\/|\\)weaver-mobile-page/,
loader: require.resolve('babel-loader'),
options: {
// @remove-on-eject-begin
babelrc: false,
plugins:[
[require.resolve('babel-plugin-transform-runtime')],
[require.resolve('babel-plugin-transform-decorators-legacy')],
[require.resolve('babel-plugin-import'), {
libraryName: 'weaver-mobile',
//style: 'css',
// style: true, // use less for customized theme
}],
],
presets: [
require.resolve('babel-preset-es2015'),
require.resolve('babel-preset-stage-0'),
require.resolve('babel-preset-react')
], //require.resolve('babel-preset-react-app'),
// @remove-on-eject-end
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
}
});
config.resolve.plugins = [];
config.plugins = config.plugins.map(p => {
if (p instanceof SWPrecacheWebpackPlugin) {
return new WorkboxWebpackPlugin.GenerateSW({
clientsClaim: true,
exclude: [/\.map$/, /asset-manifest\.json$/],
importWorkboxFrom: 'disabled',
navigateFallback: paths.servedPath + 'index.html',
importScripts: ['/cloudstore/resource/mobile/workbox-v4.3.1/workbox-sw.js'],
navigateFallbackBlacklist: [
// Exclude URLs starting with /_, as they're likely an API call
new RegExp('^/_'),
// Exclude URLs containing a dot, as they're likely a resource in
// public/ and not a SPA route
new RegExp('/[^/]+\\.[^/]+$'),
],
precacheManifestFilename: 'precache-manifest.js?v=[manifestHash]',
skipWaiting: true,
})
}
return p;
})
config.externals = [{ '$': '$'}, { 'jquery': 'jQuery' }, { 'jQuery': 'jQuery' }];
// file-loader exclude
let l = getLoader(config.module.rules, fileLoaderMatcher);
l.exclude.push(/\.less$/);
config.resolve.alias = Object.assign({}, config.resolve.alias, {
'mobx-react': 'wm-mobx-react',
'react-router': 'wm-react-router',
});
return config;
};