const os = require('os'); const path = require('path'); const webpack = require('webpack'); const slash = require('slash2'); const CopyPlugin = require('copy-webpack-plugin'); const cesiumSource = './node_modules/cesium/Build/Cesium'; const FastRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); // cpu核数 const threads = os.cpus().length; const nodeLibs = require('node-libs-browser'); console.log(); module.exports = options => ({ mode: options.mode, entry: options.entry, output: Object.assign( { path: process.env.npm_config_releasepath ? path.resolve(process.env.npm_config_releasepath, 'civmanage') : path.resolve(process.cwd(), 'civmanage'), publicPath: process.env.PUBLIC_PATH || '/civmanage/', sourcePrefix: '', // 需要编译Cesium中的多行字符串 }, options.output, ), // Merge with env dependent settings optimization: options.optimization, amd: { // 允许Cesium兼容 webpack的require方式 toUrlUndefined: true, }, module: { rules: [ { oneOf: [ { test: /\.[jt]sx?$/, exclude: /node_modules/, use: [ { loader: 'thread-loader', // 开启多进程 options: { workers: threads, // 数量 }, }, { loader: 'babel-loader', options: { ...options.babelQuery, cacheDirectory: true, // 开启babel编译缓存 cacheCompression: false, // 缓存文件不要压缩 }, // options: { // presets: ['@babel/preset-typescript'], // plugins: ['@babel/plugin-proposal-optional-chaining'], // }, }, ], }, { // Preprocess our own .css files // This is the place to add your own loaders (e.g. sass/less etc.) // for a list of loaders, see https://webpack.js.org/loaders/#styling test: /\.css$/, exclude: /node_modules/, use: ['style-loader', 'css-loader'], }, { test: /\.less$/, use: [ { loader: 'style-loader', }, { loader: 'css-loader', options: { modules: { // localIdentName: '[name]__[local]___[hash:base64:5]' // modules: true, getLocalIdent: (context, _, localName) => { if (/@wisdom-cesium/.test(context.resourcePath)) { const matchRule = slash(context.resourcePath).match( /@wisdom-cesium\/(krpano)(.*).less$/, ); if (matchRule && matchRule[2]) { if (/rc-slider/.test(matchRule[0])) { return localName; } const className = matchRule[2] .split('/') .map(a => a.replace(/([A-Z])/g, '-$1')) .map(a => a.toLowerCase()) .join('-'); return `panda-krpano-${className}-${localName}`.replace(/--/g, '-'); } return localName; } if ( context.resourcePath.includes('node_modules') || context.resourcePath.includes('ant.design.pro.less') || context.resourcePath.includes('global.less') ) { return localName; } const match = context.resourcePath.match(/src(.*)/); const matchAntd = /^ant/.test(localName); if (match && match[1] && !matchAntd) { const antdProPath = match[1].replace('.less', ''); const arr = slash(antdProPath) .split('/') .map(a => a.replace(/([A-Z])/g, '-$1')) .map(a => a.toLowerCase()); return `panda-pro${arr.join('-')}-${localName}`.replace(/--/g, '-'); } return localName; }, }, }, }, { loader: 'less-loader', options: { javascriptEnabled: true, }, }, ], }, { test: /\.css$/, include: /node_modules/, use: ['style-loader', 'css-loader'], }, { test: /\.(eot|otf|ttf|woff|woff2)$/, use: 'file-loader', }, { test: /\.svg$/, use: [ { loader: 'svg-url-loader', options: { // Inline files smaller than 10 kB limit: 10 * 1024, noquotes: true, }, }, ], }, { test: /\.(jpg|png|gif)$/, use: [ { loader: 'url-loader', options: { // Inline files smaller than 10 kB limit: 10 * 1024, outputPath: 'assets/', // name: '[name].[ext]' }, }, // { // loader: 'image-webpack-loader', // options: { // mozjpeg: { // enabled: false, // // NOTE: mozjpeg is disabled as it causes errors in some Linux environments // // Try enabling it in your environment by switching the config to: // // enabled: true, // // progressive: true, // }, // gifsicle: { // interlaced: false, // }, // optipng: { // optimizationLevel: 7, // }, // pngquant: { // quality: '65-90', // speed: 4, // }, // }, // }, ], }, { test: /\.html$/, use: 'html-loader', }, { test: /\.(mp4|webm)$/, use: { loader: 'url-loader', options: { limit: 10000, }, }, }, ], }, ], }, plugins: options.plugins.concat([ // Always expose NODE_ENV to webpack, in order to use `process.env.NODE_ENV` // inside your code for any environment checks; Terser will automatically // drop any unreachable code. new webpack.EnvironmentPlugin({ NODE_ENV: 'development', }), new webpack.ProvidePlugin({ process: nodeLibs.process, }), new FastRefreshPlugin({ overlay: false, }), new CopyPlugin([ { from: path.resolve(process.cwd(), './public'), }, { from: path.join(process.cwd(), cesiumSource, 'Workers'), to: 'Workers', }, { from: path.join(process.cwd(), cesiumSource, 'Assets'), to: 'Assets', }, { from: path.join(process.cwd(), cesiumSource, 'Widgets'), to: 'Widgets', }, { from: path.join(process.cwd(), cesiumSource, 'ThirdParty'), to: 'ThirdParty', }, ]), new webpack.DefinePlugin({ CESIUM_BASE_URL: JSON.stringify('/civmanage'), // 定义packName }), ]), resolve: { modules: ['node_modules', 'src'], extensions: ['.js', '.jsx', '.react.js', '.ts', '.tsx'], mainFields: ['browser', 'jsnext:main', 'main'], alias: { '@': path.resolve(process.cwd(), './src'), components: path.resolve(process.cwd(), './src/components'), cesium: path.resolve(process.cwd(), cesiumSource), react: path.resolve(process.cwd(), './node_modules/react'), '@esri/arcgis-html-sanitizer': path.resolve( process.cwd(), './node_modules/@esri/arcgis-html-sanitizer/dist/esm/index.js', ), }, fallback: { ...Object.keys(nodeLibs).reduce((memo, key) => { if (nodeLibs[key]) { memo[key] = nodeLibs[key]; } else { memo[key] = false; } return memo; }, {}), http: false, https: false, }, }, devtool: options.devtool, target: 'web', // Make web variables accessible to webpack, e.g. window performance: options.performance || {}, });