diff --git a/package.json b/package.json index 7a35d5a..32c40bf 100644 --- a/package.json +++ b/package.json @@ -34,73 +34,68 @@ }, "homepage": "https://github.com/o2team/athena2#readme", "dependencies": { + "@babel/core": "7.6.0", + "@babel/plugin-proposal-export-default-from": "^7.5.2", "archiver": "2.1.0", - "autoprefixer": "7.1.4", - "babel-core": "6.26.0", - "babel-loader": "7.1.2", - "babel-plugin-syntax-dynamic-import": "6.18.0", - "babel-plugin-transform-class-properties": "6.24.1", - "babel-plugin-transform-decorators-legacy": "1.3.4", - "babel-plugin-transform-es3-member-expression-literals": "6.22.0", - "babel-plugin-transform-es3-property-literals": "6.22.0", - "babel-plugin-transform-jscript": "6.22.0", - "babel-plugin-transform-object-rest-spread": "6.26.0", - "babel-plugin-transform-react-jsx": "6.24.1", - "babel-plugin-transform-remove-strict-mode": "0.0.2", - "babel-plugin-transform-runtime": "6.23.0", + "autoprefixer": "9.7.1", + "babel-loader": "8.0.6", + "babel-plugin-macros": "^2.6.1", + "babel-plugin-named-asset-import": "^0.3.4", + "babel-plugin-transform-es3-member-expression-literals": "^6.22.0", + "babel-plugin-transform-es3-property-literals": "^6.22.0", "babel-preset-env": "1.6.0", - "chalk": "2.1.0", + "babel-preset-react-app": "^9.0.2", + "chalk": "2.4.2", "clean-webpack-plugin": "0.1.17", - "commander": "2.11.0", - "css-loader": "0.28.7", + "commander": "4.0.0", + "css-loader": "3.2.0", "es3ify-loader": "0.2.0", - "exports-loader": "0.6.4", - "extract-text-webpack-plugin": "3.0.1", - "file-loader": "0.11.2", - "fs-extra": "4.0.1", - "ftps": "1.1.0", + "exports-loader": "0.7.0", + "file-loader": "4.2.0", + "fs-extra": "8.1.0", + "ftps": "1.1.1", "git-clone": "0.1.0", "hot-module-accept": "1.1.2", - "html-loader": "0.5.1", - "html-webpack-harddisk-plugin": "0.1.0", - "html-webpack-plugin": "2.30.1", - "inquirer": "3.2.2", - "lodash": "4.17.4", + "html-loader": "0.5.5", + "html-webpack-harddisk-plugin": "1.0.1", + "html-webpack-plugin": "3.2.0", + "inquirer": "7.0.0", + "lodash": "4.17.15", "mem-fs": "1.1.3", "mem-fs-editor": "3.0.2", - "node-sass": "4.5.3", - "npm-install-webpack-plugin": "4.0.5", - "ora": "1.3.0", + "mini-css-extract-plugin": "0.8.0", + "node-sass": "4.13.0", + "ora": "4.0.2", "postcss-assets": "5.0.0", - "postcss-flexbugs-fixes": "3.2.0", - "postcss-loader": "2.0.6", - "postcss-plugin-px2rem": "0.7.0", + "postcss-flexbugs-fixes": "4.1.0", + "postcss-loader": "3.0.0", + "postcss-plugin-px2rem": "0.8.1", "postcss-sprites": "4.2.1", - "request": "2.83.0", - "sass-loader": "6.0.6", + "request": "2.88.0", + "sass-loader": "8.0.0", "script-loader": "0.7.2", - "semver": "5.4.1", - "shelljs": "0.7.8", - "style-loader": "0.18.2", - "uglifyjs-webpack-plugin": "1.1.6", - "url-loader": "0.5.9", - "uuid": "3.1.0", - "vue-loader": "13.0.5", - "vue-template-compiler": "2.4.4", - "webpack": "3.10.0", - "webpack-dev-server": "2.11.1", - "webpack-manifest-plugin": "1.3.2", - "webpack-merge": "4.1.0", + "semver": "6.3.0", + "shelljs": "0.8.3", + "style-loader": "1.0.0", + "uglifyjs-webpack-plugin": "2.2.0", + "url-loader": "2.2.0", + "uuid": "3.3.3", + "vue-loader": "15.7.2", + "vue-template-compiler": "2.6.10", + "webpack": "4.41.2", + "webpack-dev-server": "3.9.0", + "webpack-manifest-plugin": "2.2.0", + "webpack-merge": "4.2.2", "zepto": "1.2.0" }, "devDependencies": { - "eslint": "^4.5.0", - "eslint-config-standard": "^10.2.1", - "eslint-plugin-import": "^2.7.0", - "eslint-plugin-node": "^5.1.1", - "eslint-plugin-promise": "^3.5.0", - "eslint-plugin-standard": "^3.0.1", - "husky": "^0.14.3", - "lint-staged": "^6.0.0" + "eslint": "^6.1.0", + "eslint-config-standard": "^14.1.0", + "eslint-plugin-import": "^2.18.2", + "eslint-plugin-node": "^10.0.0", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-standard": "^4.0.1", + "husky": "^3.0.9", + "lint-staged": "^9.4.2" } } diff --git a/src/build/build.js b/src/build/build.js index 26abe68..3ca079c 100644 --- a/src/build/build.js +++ b/src/build/build.js @@ -39,7 +39,7 @@ module.exports = function build (args, options) { } function buildCore (conf, options) { - const buildSpinner = ora(`Starting build, please waitšŸ¤”~`).start() + const buildSpinner = ora('Starting build, please waitšŸ¤”~').start() const appConf = conf.appConf const buildConfig = getAppBuildConfig(conf.appPath) const { @@ -66,21 +66,6 @@ function buildCore (conf, options) { } else { customWebpackConf = buildConfig.webpack } - let dllWebpackCompiler - let libContext - const library = buildConfig.library - let vendorFiles = [] - let libraryDir - if (conf.buildType === BUILD_APP) { - if (library && !isEmptyObject(library)) { - libraryDir = library.directory || 'lib' - libContext = path.join(conf.appPath, outputRoot, libraryDir) - fs.ensureDirSync(libContext) - const webpackDllConf = require('../config/dll.conf')(libContext, buildConfig, library) - dllWebpackCompiler = webpack(webpackDllConf) - } - } - buildConfig.library = library const webpackBaseConf = require('../config/base.conf')(conf.appPath, buildConfig, template, platform, framework) const webpackProdConf = require('../config/prod.conf')(conf.appPath, buildConfig, template, platform, framework) let webpackConf = webpackMerge(webpackBaseConf, webpackProdConf) @@ -103,117 +88,29 @@ function buildCore (conf, options) { } })) } - if (dllWebpackCompiler) { - dllWebpackCompiler.run((err, stats) => { - if (err) { - return printBuildError(err) - } - const { errors, warnings } = formatWebpackMessage(stats.toJson({}, true)) - const isSuccess = !errors.length && !warnings.length - if (isSuccess) { - webpackConf.plugins.push( - new webpack.DllReferencePlugin({ - context: libContext, - manifest: require(path.join(libContext, `${library.name || 'vendor'}-manifest.json`)) - }) - ) - if (libContext) { - vendorFiles = fs.readdirSync(libContext).map(file => { - if (/dll\.js$/.test(file)) { - return `${publicPath}${urlJoin(libraryDir, file)}` - } - return null - }).filter(Boolean) - } - if (appConf.template === 'complete') { - for (const mod in htmlPages) { - for (const page in htmlPages[mod]) { - const pageItem = htmlPages[mod][page] - webpackConf.plugins.push(new HtmlWebpackPlugin({ - filename: `${mod}/${pageItem.filename}`, - template: pageItem.filepath, - alwaysWriteToDisk: true, - chunks: [`${mod}/${page}`], - vendorFiles - })) - } - } - } else { - webpackConf.plugins.push(new HtmlWebpackPlugin({ - filename: 'index.html', - template: htmlPages['index'], - alwaysWriteToDisk: true, - chunks: 'index.js', - vendorFiles - })) - } - webpackConf = webpackMerge(webpackConf, customWebpackConf) - const compiler = createCompiler(webpack, webpackConf) - return buildCompilerRun(compiler, buildSpinner, conf, options) - } - if (errors.length) { - errors.splice(1) - buildSpinner.fail(chalk.red('Compile library failed!\n')) - return printBuildError(new Error(errors.join('\n\n'))) - } - if (warnings.length) { - buildSpinner.warn(chalk.yellow('Library Compiled with warnings.\n')) - console.log(warnings.join('\n\n')) - console.log( - '\nSearch for the ' + - chalk.underline(chalk.yellow('keywords')) + - ' to learn more about each warning.' - ) - console.log( - 'To ignore, add ' + - chalk.cyan('// eslint-disable-next-line') + - ' to the line before.\n' - ) - } - }) - } else { - if (library && !isEmptyObject(library)) { - webpackConf.plugins.push( - new webpack.DllReferencePlugin({ - context: libContext, - manifest: require(path.join(libContext, `${library.name || 'vendor'}-manifest.json`)) - }) - ) - } - if (libContext) { - vendorFiles = fs.readdirSync(libContext).map(file => { - if (/dll\.js$/.test(file)) { - return `${publicPath}${urlJoin(libraryDir, file)}` - } - return null - }).filter(Boolean) - } - if (appConf.template === 'complete') { - for (const mod in htmlPages) { - for (const page in htmlPages[mod]) { - const pageItem = htmlPages[mod][page] - webpackConf.plugins.push(new HtmlWebpackPlugin({ - filename: `${mod}/${pageItem.filename}`, - template: pageItem.filepath, - alwaysWriteToDisk: true, - chunks: [`${mod}/${page}`], - vendorFiles - })) - } + if (appConf.template === 'complete') { + for (const mod in htmlPages) { + for (const page in htmlPages[mod]) { + const pageItem = htmlPages[mod][page] + webpackConf.plugins.push(new HtmlWebpackPlugin({ + filename: `${mod}/${pageItem.filename}`, + template: pageItem.filepath, + alwaysWriteToDisk: true, + chunks: [`${mod}/${page}`] + })) } - } else { - webpackConf.plugins.push(new HtmlWebpackPlugin({ - filename: 'index.html', - template: htmlPages['index'], - alwaysWriteToDisk: true, - chunks: 'index.js', - vendorFiles - })) } - webpackConf = webpackMerge(webpackConf, customWebpackConf) - const compiler = createCompiler(webpack, webpackConf) - buildCompilerRun(compiler, buildSpinner, conf, options) + } else { + webpackConf.plugins.push(new HtmlWebpackPlugin({ + filename: 'index.html', + template: htmlPages.index, + alwaysWriteToDisk: true, + chunks: 'index.js' + })) } + webpackConf = webpackMerge(webpackConf, customWebpackConf) + const compiler = createCompiler(webpack, webpackConf) + buildCompilerRun(compiler, buildSpinner, conf, options) } function buildCompilerRun (compiler, buildSpinner, conf, options) { @@ -221,7 +118,6 @@ function buildCompilerRun (compiler, buildSpinner, conf, options) { if (err) { return printBuildError(err) } - const { errors, warnings } = formatWebpackMessage(stats.toJson({}, true)) const isSuccess = !errors.length && !warnings.length if (isSuccess) { diff --git a/src/build/index.js b/src/build/index.js index 6fa5792..1af3241 100644 --- a/src/build/index.js +++ b/src/build/index.js @@ -75,7 +75,7 @@ exports.getEntry = function ({ appConf, appPath, moduleList = [], buildConfig = if (!ext.length) { let entryPath = path.join(pagePath, item, `${item}.js`) if (!fs.existsSync(entryPath)) { - entryPath = path.join(pagePath, item, `index.js`) + entryPath = path.join(pagePath, item, 'index.js') } if (fs.existsSync(entryPath)) { entry[`${mod}/${item}`] = [ @@ -87,7 +87,7 @@ exports.getEntry = function ({ appConf, appPath, moduleList = [], buildConfig = }) } else { const simpleEntry = path.join(appPath, sourceRoot, 'index.js') - if (fs.existsSync(simpleEntry)) entry['index'] = new Array(simpleEntry) + if (fs.existsSync(simpleEntry)) entry.index = new Array(simpleEntry) } return entry @@ -112,7 +112,7 @@ exports.getPageHtml = function ({ appConf, appPath, moduleList = [], buildConfig let filename = `${item}.html` let pageHtmlPath = path.join(pagePath, item, filename) if (!fs.existsSync(pageHtmlPath)) { - filename = `index.html` + filename = 'index.html' pageHtmlPath = path.join(pagePath, item, filename) } if (fs.existsSync(pageHtmlPath)) { @@ -138,7 +138,7 @@ exports.getPageHtml = function ({ appConf, appPath, moduleList = [], buildConfig } else { const simpleHtml = path.join(appPath, sourceRoot, 'index.html') if (fs.existsSync(simpleHtml)) { - pageHtml['index'] = simpleHtml + pageHtml.index = simpleHtml } } @@ -150,6 +150,7 @@ exports.createCompiler = function (webpack, config) { try { compiler = webpack(config) } catch (err) { + console.log(err) console.log(chalk.red('Failed to compile.')) console.log() console.log(err.message || err) diff --git a/src/config/base.conf.js b/src/config/base.conf.js index 66f8854..3223bcb 100644 --- a/src/config/base.conf.js +++ b/src/config/base.conf.js @@ -10,13 +10,13 @@ module.exports = function (appPath, buildConfig, template, platform, framework) const imgLimit = (buildConfig.module && buildConfig.module.base64 && buildConfig.module.base64.imageLimit) || 2000 const fontLimit = (buildConfig.module && buildConfig.module.base64 && buildConfig.module.base64.fontLimit) || 2000 if (template === 'h5') { - imgName = 'img/[name].[ext]' - mediaName = fontName = extName = 'plugin/[name].[ext]' + imgName = 'img/[name].[hash:8].[ext]' + mediaName = fontName = extName = 'plugin/[name].[hash:8].[ext]' } else { - imgName = `${staticDirectory}/images/[name].[ext]` - mediaName = `${staticDirectory}/media/[name].[ext]` - fontName = `${staticDirectory}/fonts/[name].[ext]` - extName = `${staticDirectory}/ext/[name].[ext]` + imgName = `${staticDirectory}/images/[name].[hash:8].[ext]` + mediaName = `${staticDirectory}/media/[name].[hash:8].[ext]` + fontName = `${staticDirectory}/fonts/[name].[hash:8].[ext]` + extName = `${staticDirectory}/ext/[name].[hash:8].[ext]` } const jsConfUse = [ { @@ -24,22 +24,10 @@ module.exports = function (appPath, buildConfig, template, platform, framework) options: { cacheDirectory: true, presets: [ - [require('babel-preset-env'), { - targets: { - browsers: browserList[platform], - uglify: true, - loose: false, - useBuiltIns: true - } - }] + [require('babel-preset-react-app'), { flow: false, typescript: true }] ], plugins: [ - require('babel-plugin-transform-decorators-legacy').default, - require('babel-plugin-transform-class-properties'), - require('babel-plugin-transform-object-rest-spread'), - require('babel-plugin-syntax-dynamic-import'), - require('babel-plugin-transform-jscript'), - require('babel-plugin-transform-remove-strict-mode') + require('@babel/plugin-proposal-export-default-from').default ].concat( platform === 'pc' ? [ require('babel-plugin-transform-es3-member-expression-literals'), @@ -47,13 +35,13 @@ module.exports = function (appPath, buildConfig, template, platform, framework) ] : [] ).concat( framework === 'nerv' ? [ - [require('babel-plugin-transform-react-jsx'), { + [require('@babel/plugin-transform-react-jsx').default, { pragma: 'Nerv.createElement' }] ] : [] ).concat( framework === 'react' ? [ - [require('babel-plugin-transform-react-jsx')] + [require('@babel/plugin-transform-react-jsx').default] ] : [] ) } diff --git a/src/config/dev.conf.js b/src/config/dev.conf.js index 55e53c4..9f47960 100644 --- a/src/config/dev.conf.js +++ b/src/config/dev.conf.js @@ -1,11 +1,10 @@ const webpack = require('webpack') -const NpmInstallPlugin = require('npm-install-webpack-plugin') const { getPostcssPlugins } = require('./postcss.conf') -const { shouldUseCnpm } = require('../util') module.exports = function (appPath, buildConfig, template, platform, framework) { return { + mode: 'development', devtool: 'cheap-module-eval-source-map', module: { rules: [ @@ -36,12 +35,6 @@ module.exports = function (appPath, buildConfig, template, platform, framework) ] }, plugins: [ - new NpmInstallPlugin({ - dev: false, - peerDependencies: true, - quiet: false, - npm: shouldUseCnpm() ? 'cnpm' : 'npm' - }), new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin() ] diff --git a/src/config/postcss.conf.js b/src/config/postcss.conf.js index e7b31e9..b71e763 100644 --- a/src/config/postcss.conf.js +++ b/src/config/postcss.conf.js @@ -16,7 +16,7 @@ exports.getPostcssPlugins = function (buildConfig = {}, platform = 'pc', templat const customPlugins = customPostcssConf.plugins || [] plugins.push(require('postcss-flexbugs-fixes')) const defaultAutoprefixerConf = { - browsers: browserList[platform], + overrideBrowserslist: browserList[platform], flexbox: 'no-2009' } diff --git a/src/config/prod.conf.js b/src/config/prod.conf.js index baba9a0..f0624ac 100644 --- a/src/config/prod.conf.js +++ b/src/config/prod.conf.js @@ -1,5 +1,5 @@ const path = require('path') -const ExtractTextPlugin = require('extract-text-webpack-plugin') +const MiniCssExtractPlugin = require('mini-css-extract-plugin') const ManifestPlugin = require('webpack-manifest-plugin') const CleanWebpackPlugin = require('clean-webpack-plugin') const UglifyJsPlugin = require('uglifyjs-webpack-plugin') @@ -38,45 +38,18 @@ module.exports = function (appPath, buildConfig, template, platform, framework) js: defaultJSCompressConf }, buildConfig.module.compress) - if (outputCSS && !isEmptyObject(outputCSS)) { - for (const key in outputCSS) { - const extractFile = new ExtractTextPlugin(key) - const include = (outputCSS[key] || []).map(item => path.join(appPath, sourceRoot, item)) - cssLoaders.push({ - test: /\.(css|scss|sass)(\?.*)?$/, - include, - loader: extractFile.extract({ - fallback: require.resolve('style-loader'), - use: [ - { - loader: require.resolve('css-loader'), - options: { - importLoaders: 1, - minimize: true, - sourceMap - } - }, - { - loader: require.resolve('postcss-loader'), - options: { - ident: 'postcss', - plugins: () => getPostcssPlugins(buildConfig, platform, template) - } - }, - require.resolve('sass-loader') - ] - }) - }) - cssExtractPlugins.push(extractFile) - } - cssLoaders.push({ - test: /\.(css|scss|sass)(\?.*)?$/, + cssLoaders.push({ + test: /\.(css|scss|sass)(\?.*)?$/, + rules: [{ use: [ - require.resolve('style-loader'), + { + loader: MiniCssExtractPlugin.loader + }, { loader: require.resolve('css-loader'), options: { - importLoaders: 1 + importLoaders: 1, + sourceMap } }, { @@ -88,50 +61,18 @@ module.exports = function (appPath, buildConfig, template, platform, framework) }, require.resolve('sass-loader') ] - }) - } else { - cssLoaders.push({ - test: /\.(css|scss|sass)(\?.*)?$/, - loader: ExtractTextPlugin.extract({ - fallback: require.resolve('style-loader'), - use: [ - { - loader: require.resolve('css-loader'), - options: { - importLoaders: 1, - minimize: compress.css, - sourceMap - } - }, - { - loader: require.resolve('postcss-loader'), - options: { - ident: 'postcss', - plugins: () => getPostcssPlugins(buildConfig, platform, template) - } - }, - require.resolve('sass-loader') - ] - }) - }) - cssExtractPlugins.push(new ExtractTextPlugin({ - filename: 'css/[name].css' - })) - } + }] + }) + cssExtractPlugins.push(new MiniCssExtractPlugin({ + filename: 'css/[name].css', + chunkFilename: 'css/[name].css' + })) const plugins = [ new CleanWebpackPlugin(path.join(appPath, outputRoot), { verbose: false, exclude: [library && library.directory ? library.directory : ''] }), - new UglifyJsPlugin({ - cache: true, - parallel: true, - sourceMap, - uglifyOptions: Object.assign({}, { - ie8: platform === 'pc' - }, compress.js) - }), ...cssExtractPlugins ] @@ -144,6 +85,7 @@ module.exports = function (appPath, buildConfig, template, platform, framework) } return { + mode: 'production', devtool: devtool, module: { rules: [ @@ -161,6 +103,21 @@ module.exports = function (appPath, buildConfig, template, platform, framework) resolve: { mainFields: ['main'] }, - plugins: plugins + plugins: plugins, + optimization: { + minimizer: [ + new UglifyJsPlugin({ + cache: true, + parallel: true, + sourceMap, + uglifyOptions: Object.assign({}, { + ie8: platform === 'pc' + }, compress.js) + }) + ], + splitChunks: { + name: false + } + } } }