import path from 'path' ; import webpack from 'webpack' ; import TerserPlugin from 'terser-webpack-plugin' ; import { GojiTarget } from '@goji/core' ; import MiniCssExtractPlugin from 'mini-css-extract-plugin' ; import type { NonUndefined } from 'utility-types' ; import { GojiWebpackPluginOptions , GojiWebpackPlugin } from '@goji/webpack-plugin' ; import nodeLibsBrowser from 'node-libs-browser' ; import resolve from 'resolve' ; import { version as babelCoreVersion } from '@babel/core/package.json' ; import { version as babelLoaderVersion } from 'babel-loader/package.json' ; import postcssConfig from './postcssConfig' ; import { getThreadLoader } from './loaders' ; const getSourceMap = ( nodeEnv , target ) : webpack . Configuration [ 'devtool' ] => { if ( nodeEnv === 'development' ) { return 'cheap-source-map' ; } if ( target === 'wechat' ) { return 'source-map' ; } return false ; } ; const getNodeLibsFallback = ( ) => { const alias = { } ; for ( const key of Object . keys ( nodeLibsBrowser ) ) { alias [ key ] = nodeLibsBrowser [ key ] ?? false ; } return alias ; } ; export const getWebpackConfig = ( { basedir , outputPath , target , nodeEnv , babelConfig , watch , progress , nohoist , } ) : webpack . Configuration => { const threadLoaders = getThreadLoader ( nodeEnv ) ; const CSS_FILE_EXT = { wechat : 'wxss' , qq : 'qss' , baidu : 'css' , alipay : 'acss' , toutiao : 'ttss' , } ; return { mode : nodeEnv === 'production' ? 'production' : 'development' , devtool : getSourceMap ( nodeEnv , target ) , context : path . resolve ( basedir , 'src' ) , entry : './app.config.ts' , resolve : { alias : { 'react-native$' : resolve . sync ( '@goji/core/dist/esm' , { basedir } ) , } , fallback : getNodeLibsFallback ( ) , extensions : [ '.native.js' , '.mjs' , '.js' , '.ts' , '.jsx' , '.tsx' , '.json' ] , } , output : { path : outputPath ?? path . join ( basedir , 'dist' , target ) , filename : '[name].js' , assetModuleFilename : 'assets/[name].[hash:6][ext]' , publicPath : '/' , globalObject : 'Object' , clean : true , } , optimization : { minimize : nodeEnv === 'production' , minimizer : [ new TerserPlugin ( { terserOptions : { format : { comments : false , } , compress : { passes : 2 , } , } , extractComments : false , } ) , ] , runtimeChunk : false , splitChunks : false , } , watch , watchOptions : { poll : GojiWebpackPlugin . getPoll ( ) , } , cache : { type : 'filesystem' , idleTimeout : 0 , idleTimeoutForInitialStore : 0 , version : target , } , stats : { preset : 'minimal' , errorDetails : true , builtAt : true , colors : true , } , performance : { hints : false , } , module : { rules : [ { test : /\.m?js$/ , resolve : { fullySpecified : false , } , } , { test : /\.(js|jsx|ts|tsx)$/ , exclude : nodeEnv === 'production' ? /node_modules\/@babel\/runtime/ : /node_modules/ , use : [ { loader : require . resolve ( './fixBabelLoaderForMacro' ) , options : { plugins : [ [ require . resolve ( 'babel-plugin-macros' ) , { gojiMacro : { target } } ] ] , } , } , ... threadLoaders , { loader : require . resolve ( 'babel-loader' ) , options : { ... babelConfig , cacheDirectory : true , cacheIdentifier : JSON . stringify ( { babelConfig , '@babel/core' : babelCoreVersion , 'babel-loader' : babelLoaderVersion , nodeEnv , target , } ) , } , } , { loader : require . resolve ( 'linaria/loader' ) , options : { configFile : require . resolve ( './linaria.config' ) , sourceMap : true , cacheProvider : require . resolve ( './linariaFileCache' ) , babelOptions : { configFile : require . resolve ( './babel.config' ) , } , } , } , ] , } , { test : /\.css$/ , exclude : /\.linaria\.css$/ , use : [ MiniCssExtractPlugin . loader , { loader : require . resolve ( 'css-loader' ) , options : { modules : { mode : 'local' , localIdentName : nodeEnv === 'development' ? '[local]__[name]--[hash:base64:5]' : '[hash:base64:5]' , localIdentContext : path . resolve ( basedir , 'src' ) , } , } , } , { loader : require . resolve ( '@goji/webpack-plugin/dist/cjs/loaders/transform' ) , options : { target , type : 'wxss' , } , } , { loader : require . resolve ( 'postcss-loader' ) , options : { implementation : require . resolve ( 'postcss' ) , postcssOptions : { config : false , ... postcssConfig , } , } , } , { loader : require . resolve ( 'postcss-loader' ) , options : { implementation : require . resolve ( 'postcss' ) , postcssOptions : { config : false , plugins : [ require ( 'postcss-import' ) ( { } ) ] , } , } , } , ] , } , { test : /\.linaria\.css$/ , use : [ MiniCssExtractPlugin . loader , { loader : require . resolve ( 'css-loader' ) , } , { loader : require . resolve ( '@goji/webpack-plugin/dist/cjs/loaders/transform' ) , options : { target , type : 'wxss' , } , } , { loader : require . resolve ( 'postcss-loader' ) , options : { implementation : require . resolve ( 'postcss' ) , postcssOptions : { config : false , ... postcssConfig , } , } , } , { loader : require . resolve ( 'postcss-loader' ) , options : { implementation : require . resolve ( 'postcss' ) , postcssOptions : { config : false , plugins : [ require ( 'postcss-import' ) ( { } ) ] , } , } , } , ] , } , { test : /\.(png|jpg|jpeg|gif)$/ , type : 'asset/resource' , } , ] , } , plugins : [ new MiniCssExtractPlugin ( { filename : `[name].${ CSS_FILE_EXT [ target ] ?? 'wxss' }` , chunkFilename : `[name].${ CSS_FILE_EXT [ target ] ?? 'wxss' }` , ignoreOrder : true , } ) , new GojiWebpackPlugin ( { target , nohoist , } ) , new webpack . DefinePlugin ( { 'process.env.NODE_ENV' : JSON . stringify ( nodeEnv ) , } ) , new webpack . ProvidePlugin ( { process : nodeLibsBrowser . process , Buffer : [ nodeLibsBrowser . buffer , 'Buffer' ] , } ) , progress && new webpack . ProgressPlugin ( ) , ] . filter ( Boolean ) , } ; } ;