UNPKG

ecology9-src4js-tools

Version:

src4js-tools

425 lines (391 loc) 14.1 kB
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; };