Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const { readdirSync } = require('fs');
- const { parse, resolve, dirname, format } = require('path');
- function interpolate(template, context) {
- return template.replace(/\[(\w+)\]/g, (_, key) => context[key] || key);
- }
- function isNodeModule(filename) {
- return !filename.startsWith('.');
- }
- /*
- * babel-plugin-alt-import-require
- *
- * Example
- * plugins: [['babel-plugin-alt-import-require', { alt: '[name].mobile[ext]' }], ...otherPlugins]
- *
- * File structure
- * code
- * \
- * |_ components
- * | \
- * | |_ App.js
- * | |_ App.mobile.js
- * |
- * |_ containers
- * \
- * |_ Main.js
- *
- * Main.js
- * ```
- * import App from '../components/App';
- * // or
- * const App = require('../components/App');
- * ```
- *
- * If you're using the plugin after babel has run Main.js would look like this
- *
- * Main.js
- * ```
- * import App from '/code/components/App.mobile.js';
- * // or
- * const App = require('/code/components/App.mobile.js'');
- * ```
- */
- // make cache 'global' to all instances of the plugin
- const cache = new Map();
- module.exports = function(babel) {
- const { types: t } = babel;
- function getAltFile(value, state) {
- const { alt } = state.opts;
- const filename = state.file.opts.filename;
- // if the required/imported file is a node module or
- // there is no alt option bail out
- if (isNodeModule(value) || !alt) return null;
- // get the absolute path the file being processed using the
- // node resolution algo to handle index.js files
- const resolved = require.resolve(resolve(dirname(filename), value));
- const path = parse(resolved);
- const altFile = interpolate(alt, path);
- // if the file being processed is the alt file bail out
- if (path.base === altFile) {
- return null;
- }
- let files;
- // check the cache to see if the dir has been processed before
- if (!cache.has(path.dir)) {
- files = readdirSync(path.dir);
- cache.set(path.dir, files);
- } else {
- files = cache.get(path.dir);
- }
- const hasAltFile = files.includes(altFile);
- return hasAltFile ? format({ ...path, base: altFile }) : null;
- }
- return {
- name: 'alt-import-require',
- visitor: {
- ImportDeclaration(path, state) {
- const altFile = getAltFile(path.node.source.value, state);
- if (altFile) {
- path.node.source.value = altFile;
- }
- },
- CallExpression(path, state) {
- if (t.isIdentifier(path.node.callee, { name: 'require' })) {
- const altFile = getAltFile(path.node.arguments[0].value, state);
- if (altFile) {
- path.node.arguments[0].value = altFile;
- }
- }
- },
- },
- };
- };
Add Comment
Please, Sign In to add comment