@expo/webpack-config
Version:
The default Webpack configuration used to build Expo apps targeting the web.
125 lines • 6.26 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = __importDefault(require("path"));
const env_1 = require("../env");
const loaders_1 = require("../loaders");
const plugins_1 = require("../plugins");
const utils_1 = require("../utils");
const withAlias_1 = __importDefault(require("./withAlias"));
const withEntry_1 = __importDefault(require("./withEntry"));
// import ManifestPlugin from 'webpack-manifest-plugin';
// Wrap your existing webpack config with support for Unimodules.
// ex: Storybook `({ config }) => withUnimodules(config)`
function withUnimodules(inputWebpackConfig = {}, env = {}, argv = {}) {
inputWebpackConfig = withAlias_1.default(inputWebpackConfig);
if (!inputWebpackConfig.module)
inputWebpackConfig.module = { rules: [] };
else if (!inputWebpackConfig.module.rules)
inputWebpackConfig.module = Object.assign(Object.assign({}, inputWebpackConfig.module), { rules: [] });
if (!inputWebpackConfig.plugins)
inputWebpackConfig.plugins = [];
if (!inputWebpackConfig.resolve)
inputWebpackConfig.resolve = {};
if (!inputWebpackConfig.output)
inputWebpackConfig.output = {};
// @ts-ignore: We should attempt to use the project root that the other config is already using (used for Gatsby support).
env.projectRoot = env.projectRoot || inputWebpackConfig.context;
// Attempt to use the input webpack config mode
env.mode = env.mode || inputWebpackConfig.mode;
const environment = env_1.validateEnvironment(env);
let { supportsFontLoading } = argv;
// If the args don't specify this then we'll check if the input already supports font loading.
if (typeof supportsFontLoading === 'undefined') {
const supportedFonts = ['ttf', 'otf', 'woff', 'woff2', 'eot'];
const testFontFileNames = supportedFonts.map(ext => path_1.default.resolve(environment.projectRoot, `cool-font.${ext}`));
if (utils_1.rulesMatchAnyFiles(inputWebpackConfig, testFontFileNames)) {
supportsFontLoading = false;
}
}
const { platform = 'web' } = env;
const config = argv.expoConfig || env_1.getConfig(environment);
const locations = env.locations || env_1.getPaths(environment.projectRoot);
const mode = env_1.getMode(env);
const { build: buildConfig = {} } = config.web || {};
const { babel: babelAppConfig = {} } = buildConfig;
const babelProjectRoot = babelAppConfig.root || locations.root;
const babelLoader = loaders_1.createBabelLoader({
mode,
platform,
babelProjectRoot,
verbose: babelAppConfig.verbose,
include: babelAppConfig.include,
use: babelAppConfig.use,
});
function reuseOrCreatePublicPaths() {
if (inputWebpackConfig.output && inputWebpackConfig.output.publicPath) {
const publicPath = inputWebpackConfig.output.publicPath;
return {
publicPath,
publicUrl: publicPath.endsWith('/') ? publicPath.slice(0, -1) : publicPath,
};
}
return env_1.getPublicPaths(environment);
}
const { publicPath, publicUrl } = reuseOrCreatePublicPaths();
inputWebpackConfig.mode = mode;
inputWebpackConfig.output = Object.assign(Object.assign({}, inputWebpackConfig.output), { publicPath });
inputWebpackConfig.plugins.push(
// Generate a manifest file which contains a mapping of all asset filenames
// to their corresponding output file so that tools can pick it up without
// having to parse `index.html`.
// new ManifestPlugin({
// fileName: 'asset-manifest.json',
// publicPath,
// }),
// Used for surfacing information related to constants
new plugins_1.ExpoDefinePlugin({
mode,
publicUrl,
config,
productionManifestPath: locations.production.manifest,
}));
const rules = [
...inputWebpackConfig.module.rules,
// TODO: Bacon: Auto remove this loader
{
test: /\.html$/,
use: ['html-loader'],
exclude: locations.template.folder,
},
// Process application code with Babel.
babelLoader,
supportsFontLoading && loaders_1.createFontLoader(locations.root, locations.includeModule),
].filter(Boolean);
inputWebpackConfig.module = Object.assign(Object.assign({}, inputWebpackConfig.module), { rules });
inputWebpackConfig.resolve = Object.assign(Object.assign({}, inputWebpackConfig.resolve), { symlinks: false,
// Support platform extensions like .web.js
extensions: env_1.getModuleFileExtensions('web') });
// We have to transpile these modules and make them not external too.
// We have to do this because next.js by default externals all `node_modules`'s js files.
// Reference:
// https://github.com/martpie/next-transpile-modules/blob/77450a0c0307e4b650d7acfbc18641ef9465f0da/index.js#L48-L62
// https://github.com/zeit/next.js/blob/0b496a45e85f3c9aa3cf2e77eef10888be5884fc/packages/next/build/webpack-config.ts#L185-L258
// `include` function is from https://github.com/expo/expo-cli/blob/3933f3d6ba65bffec2738ece71b62f2c284bd6e4/packages/webpack-config/webpack/loaders/createBabelLoaderAsync.js#L76-L96
const includeFunc = babelLoader.include;
if (inputWebpackConfig.externals) {
inputWebpackConfig.externals = inputWebpackConfig.externals.map((external) => {
if (typeof external !== 'function')
return external;
return (ctx, req, cb) => {
const relPath = path_1.default.join('node_modules', req);
return includeFunc(relPath) ? cb() : external(ctx, req, cb);
};
});
}
// Add a loose requirement on the ResizeObserver polyfill if it's installed...
inputWebpackConfig = withEntry_1.default(inputWebpackConfig, env, {
entryPath: 'resize-observer-polyfill/dist/ResizeObserver.global',
});
return inputWebpackConfig;
}
exports.default = withUnimodules;
//# sourceMappingURL=withUnimodules.js.map