Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable custom source file extensions through cli args or rn-cli.config.js #13689

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions local-cli/bundle/buildBundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const outputBundle = require('./output/bundle');
const path = require('path');
const saveAssets = require('./saveAssets');
const defaultAssetExts = require('../../packager/defaults').assetExts;
const defaultSourceExts = require('../../packager/defaults').sourceExts;
const defaultPlatforms = require('../../packager/defaults').platforms;
const defaultProvidesModuleNodeModules = require('../../packager/defaults').providesModuleNodeModules;

Expand Down Expand Up @@ -64,6 +65,7 @@ function buildBundle(
var shouldClosePackager = false;
if (!packagerInstance) {
const assetExts = (config.getAssetExts && config.getAssetExts()) || [];
const sourceExts = (config.getSourceExts && config.getSourceExts()) || [];
const platforms = (config.getPlatforms && config.getPlatforms()) || [];

const transformModulePath =
Expand All @@ -87,6 +89,7 @@ function buildBundle(
providesModuleNodeModules: providesModuleNodeModules,
resetCache: args.resetCache,
reporter: new TerminalReporter(),
sourceExts: defaultSourceExts.concat(sourceExts),
transformModulePath: transformModulePath,
watch: false,
};
Expand Down
3 changes: 3 additions & 0 deletions local-cli/core/default.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ const config: ConfigT = {
getAssetExts() {
return [];
},
getSourceExts() {
return [];
},
getPlatforms() {
return [];
},
Expand Down
8 changes: 8 additions & 0 deletions local-cli/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ export type ConfigT = {
* from here and use `require('./fonts/example.ttf')` inside your app.
*/
getAssetExts?: () => Array<string>,
/**
* Specify any additional source file extentions to be used by the packager.
* For example, if you want to include a .ts file, you would return ['ts']
* from here and use `require('./module/example')` to require the file with
* path 'module/example.ts' inside your app.
*/
getSourceExts?: () => Array<string>,
/**
* Specify any additional platforms to be used by the packager.
* For example, if you want to add a "custom" platform, and use modules
Expand All @@ -55,6 +62,7 @@ export type ConfigT = {
getBlacklistRE(): RegExp,
getProjectRoots(): Array<string>,
getAssetExts(): Array<string>,
getSourceExts(): Array<string>,
/**
* Returns an array of project commands used by the CLI to load
*/
Expand Down
2 changes: 2 additions & 0 deletions local-cli/server/runServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const connect = require('connect');
const copyToClipBoardMiddleware = require('./middleware/copyToClipBoardMiddleware');
const cpuProfilerMiddleware = require('./middleware/cpuProfilerMiddleware');
const defaultAssetExts = require('../../packager/defaults').assetExts;
const defaultSourceExts = require('../../packager/defaults').sourceExts;
const defaultPlatforms = require('../../packager/defaults').platforms;
const defaultProvidesModuleNodeModules = require('../../packager/defaults').providesModuleNodeModules;
const getDevToolsMiddleware = require('./middleware/getDevToolsMiddleware');
Expand Down Expand Up @@ -114,6 +115,7 @@ function getPackagerServer(args, config) {
providesModuleNodeModules: providesModuleNodeModules,
reporter: new LogReporter(),
resetCache: args.resetCache,
sourceExts: defaultSourceExts.concat(args.sourceExts),
transformModulePath: transformModulePath,
verbose: args.verbose,
watch: !args.nonPersistent,
Expand Down
5 changes: 5 additions & 0 deletions local-cli/server/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ module.exports = {
description: 'Specify any additional asset extentions to be used by the packager',
parse: (val) => val.split(','),
default: (config) => config.getAssetExts(),
}, {
command: '--sourceExts [list]',
description: 'Specify any additional source extentions to be used by the packager',
parse: (val) => val.split(','),
default: (config) => config.getSourceExts(),
}, {
command: '--platforms [list]',
description: 'Specify any additional platforms to be used by the packager',
Expand Down
2 changes: 2 additions & 0 deletions packager/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ exports.assetExts = [
'html', 'pdf', // Document formats
];

exports.sourceExts = ['js', 'json'];

exports.moduleSystem = require.resolve('./src/Resolver/polyfills/require.js');

exports.platforms = ['ios', 'android', 'windows', 'web'];
Expand Down
4 changes: 4 additions & 0 deletions packager/rn-cli.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ module.exports = {
return [];
},

getSourceExts() {
return [];
},

getBlacklistRE() {
return blacklist();
},
Expand Down
1 change: 1 addition & 0 deletions packager/src/Bundler/__tests__/Bundler-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ var commonOptions = {
extraNodeModules: {},
platforms: defaults.platforms,
resetCache: false,
sourceExts: defaults.sourceExts,
watch: false,
};

Expand Down
2 changes: 2 additions & 0 deletions packager/src/Bundler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ type Options = {|
+providesModuleNodeModules?: Array<string>,
+reporter: Reporter,
+resetCache: boolean,
+sourceExts: Array<string>,
+transformModulePath?: string,
+transformTimeoutInterval: ?number,
+watch: boolean,
Expand Down Expand Up @@ -200,6 +201,7 @@ class Bundler {
opts.providesModuleNodeModules || defaults.providesModuleNodeModules,
reporter: opts.reporter,
resetCache: opts.resetCache,
sourceExts: opts.sourceExts,
transformCode:
(module, code, transformCodeOptions) => this._transformer.transformFile(
module.path,
Expand Down
5 changes: 4 additions & 1 deletion packager/src/ModuleGraph/node-haste/node-haste.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const defaults = require('../../../defaults');

type ResolveOptions = {|
assetExts: Extensions,
sourceExts: Extensions,
extraNodeModules: {[id: string]: string},
transformedFiles: {[path: Path]: TransformedFile},
|};
Expand Down Expand Up @@ -72,6 +73,7 @@ exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
assetExts,
extraNodeModules,
transformedFiles,
sourceExts,
} = options;
const files = Object.keys(transformedFiles);
function getTransformedFile(path) {
Expand All @@ -93,7 +95,7 @@ exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
getTransformedFile,
);
const hasteMap = new HasteMap({
extensions: ['js', 'json'],
extensions: sourceExts,
files,
helpers,
moduleCache,
Expand All @@ -119,6 +121,7 @@ exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
platform,
platforms,
preferNativePlatform: true,
sourceExts,
});
}

Expand Down
2 changes: 1 addition & 1 deletion packager/src/Resolver/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Options = {|
+providesModuleNodeModules: Array<string>,
+reporter: Reporter,
+resetCache: boolean,
+sourceExts: Array<string>,
+transformCode: TransformCode,
+watch: boolean,
|};
Expand All @@ -63,7 +64,6 @@ class Resolver {
static async load(opts: Options): Promise<Resolver> {
const depGraphOpts = Object.assign(Object.create(opts), {
assetDependencies: ['react-native/Libraries/Image/AssetRegistry'],
extensions: ['js', 'json'],
forceNodeFilesystemAPI: false,
ignoreFilePath(filepath) {
return filepath.indexOf('__tests__') !== -1 ||
Expand Down
3 changes: 3 additions & 0 deletions packager/src/Server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ type Options = {
reporter: Reporter,
resetCache?: boolean,
silent?: boolean,
sourceExts?: Array<string>,
transformModulePath?: string,
transformTimeoutInterval?: number,
watch?: boolean,
Expand Down Expand Up @@ -144,6 +145,7 @@ class Server {
reporter: Reporter,
resetCache: boolean,
silent: boolean,
sourceExts: Array<string>,
transformModulePath: void | string,
transformTimeoutInterval: ?number,
watch: boolean,
Expand Down Expand Up @@ -179,6 +181,7 @@ class Server {
reporter: options.reporter,
resetCache: options.resetCache || false,
silent: options.silent || false,
sourceExts: options.sourceExts || defaults.sourceExts,
transformModulePath: options.transformModulePath,
transformTimeoutInterval: options.transformTimeoutInterval,
watch: options.watch || false,
Expand Down
40 changes: 27 additions & 13 deletions packager/src/node-haste/DependencyGraph/ResolutionRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ type Options<TModule, TPackage> = {|
+platform: ?string,
+platforms: Set<string>,
+preferNativePlatform: boolean,
+sourceExts: Array<string>,
|};

/**
Expand Down Expand Up @@ -102,6 +103,7 @@ class ResolutionRequest<TModule: Moduleish, TPackage: Packageish> {
_platform: ?string;
_platforms: Set<string>;
_preferNativePlatform: boolean;
_sourceExts: Array<string>;
static emptyModule: string;

constructor({
Expand All @@ -116,6 +118,7 @@ class ResolutionRequest<TModule: Moduleish, TPackage: Packageish> {
platform,
platforms,
preferNativePlatform,
sourceExts,
}: Options<TModule, TPackage>) {
this._dirExists = dirExists;
this._entryPath = entryPath;
Expand All @@ -128,6 +131,7 @@ class ResolutionRequest<TModule: Moduleish, TPackage: Packageish> {
this._platform = platform;
this._platforms = platforms;
this._preferNativePlatform = preferNativePlatform;
this._sourceExts = sourceExts;
this._resetResolutionCache();
}

Expand Down Expand Up @@ -559,22 +563,32 @@ class ResolutionRequest<TModule: Moduleish, TPackage: Packageish> {
let file;
if (this._hasteFS.exists(potentialModulePath)) {
file = potentialModulePath;
} else if (this._platform != null &&
this._hasteFS.exists(potentialModulePath + '.' + this._platform + '.js')) {
file = potentialModulePath + '.' + this._platform + '.js';
} else if (this._preferNativePlatform &&
this._hasteFS.exists(potentialModulePath + '.native.js')) {
file = potentialModulePath + '.native.js';
} else if (this._hasteFS.exists(potentialModulePath + '.js')) {
file = potentialModulePath + '.js';
} else if (this._hasteFS.exists(potentialModulePath + '.json')) {
file = potentialModulePath + '.json';
} else {
throw new UnableToResolveError(
fromModule,
toModule,
`File ${potentialModulePath} doesn't exist`,
);
for (let i = 0; i < this._sourceExts.length; i++) {
const ext = this._sourceExts[i];
if (this._platform != null &&
this._hasteFS.exists(potentialModulePath + '.' + this._platform + '.' + ext)) {
file = potentialModulePath + '.' + this._platform + '.' + ext;
break;
} else if (this._preferNativePlatform &&
this._hasteFS.exists(potentialModulePath + '.native.' + ext)) {
file = potentialModulePath + '.native.' + ext;
break;
} else if (this._hasteFS.exists(potentialModulePath + '.' + ext)) {
file = potentialModulePath + '.' + ext;
break;
}
}

if (file === undefined) {
throw new UnableToResolveError(
fromModule,
toModule,
`File ${potentialModulePath} doesn't exist`,
);
}
}

return this._moduleCache.getModule(file);
Expand Down
81 changes: 79 additions & 2 deletions packager/src/node-haste/__tests__/DependencyGraph-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ describe('DependencyGraph', function() {
emptyTransformOptions = {transformer: {transform: {}}};
defaults = {
assetExts: ['png', 'jpg'],
extensions: ['js', 'json'],
sourceExts: ['js', 'json'],
forceNodeFilesystemAPI: true,
providesModuleNodeModules: [
'haste-fbjs',
Expand Down Expand Up @@ -5250,7 +5250,7 @@ describe('DependencyGraph', function() {
var dgraph = DependencyGraph.load({
...defaults,
roots: [root],
extensions: ['jsx', 'coffee'],
sourceExts: ['jsx', 'coffee'],
});

return dgraph
Expand Down Expand Up @@ -5284,6 +5284,83 @@ describe('DependencyGraph', function() {
]);
});
});
it('supports custom file extensions with relative paths', () => {
var root = '/root';
setMockFileSystem({
'root': {
'index.jsx': [
'require("./a")',
].join('\n'),
'a.coffee': [
].join('\n'),
'X.js': '',
},
});

var dgraph = DependencyGraph.load({
...defaults,
roots: [root],
sourceExts: ['jsx', 'coffee'],
});

return dgraph
.then(dg => dg.matchFilesByPattern('.*'))
.then(files => {
expect(files).toEqual([
'/root/index.jsx', '/root/a.coffee',
]);
})
.then(() => getOrderedDependenciesAsJSON(dgraph, '/root/index.jsx'))
.then(deps => {
expect(deps).toEqual([
{
dependencies: ['./a'],
id: '/root/index.jsx',
isAsset: false,
isJSON: false,
isPolyfill: false,
path: '/root/index.jsx',
resolution: undefined,
},
{
dependencies: [],
id: '/root/a.coffee',
isAsset: false,
isJSON: false,
isPolyfill: false,
path: '/root/a.coffee',
resolution: undefined,
},
]);
});
});

it('does not support custom extensious without sourceExts', (done) => {
var root = '/root';
setMockFileSystem({
'root': {
'index.jsx': [
'require("./a")',
].join('\n'),
'a.coffee': [
].join('\n'),
'X.js': '',
},
});

var dgraph = DependencyGraph.load({
...defaults,
roots: [root],
});

dgraph
.then(dg => dg.matchFilesByPattern('.*'))
.then(files => {
expect(files).toEqual(['/root/X.js']);
})
.then(() => getOrderedDependenciesAsJSON(dgraph, '/root/index.jsx'))
.catch(done);
});
});

describe('Progress updates', () => {
Expand Down
Loading