From this other answer on the WP SE
add_action('generate_rewrite_rules', 'roots_add_rewrites');
function roots_add_rewrites($content) {
$theme_name = next(explode('/themes/', get_stylesheet_directory()));
global $wp_rewrite;
$roots_new_non_wp_rules = array(
'css/(.*)' => 'wp-content/themes/'. $theme_name . '/css/$1',
'js/(.*)' => 'wp-content/themes/'. $theme_name . '/js/$1',
'img/(.*)' => 'wp-content/themes/'. $theme_name . '/img/$1',
);
$wp_rewrite->non_wp_rules += $roots_new_non_wp_rules;
}
TheDeadMedic provided a much better version of this function:
function wpse_208051_add_rewrites( $wp_rewrite ) {
$path = str_replace( home_url( "https://wordpress.stackexchange.com/" ), '', get_template_directory_uri() );
$wp_rewrite->non_wp_rules += array(
'css/(.*)' => $path . '/css/$1',
'js/(.*)' => $path . '/js/$1',
'img/(.*)' => $path . '/img/$1',
);
}
add_action( 'generate_rewrite_rules', 'wpse_208051_add_rewrites' );