mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-15 02:54:11 +08:00

* feat: use raw-loader for all css but app.s?css * feat: use angular css rules for entire app dir Co-authored-by: Eduardo Speroni <edusperoni@gmail.com>
237 lines
7.2 KiB
TypeScript
237 lines
7.2 KiB
TypeScript
import { extname, resolve } from 'path';
|
|
import Config from 'webpack-chain';
|
|
import { existsSync } from 'fs';
|
|
|
|
import { getProjectFilePath } from '../helpers/project';
|
|
import { env as _env, IWebpackEnv } from '../index';
|
|
import {
|
|
getEntryDirPath,
|
|
getEntryPath,
|
|
getPlatformName,
|
|
} from '../helpers/platform';
|
|
import base from './base';
|
|
|
|
export default function (config: Config, env: IWebpackEnv = _env): Config {
|
|
base(config, env);
|
|
|
|
const platform = getPlatformName();
|
|
|
|
const tsConfigPath = [
|
|
getProjectFilePath('tsconfig.app.json'),
|
|
getProjectFilePath('tsconfig.json'),
|
|
].find((path) => existsSync(path));
|
|
|
|
// remove default ts rule
|
|
config.module.rules.delete('ts');
|
|
|
|
// remove fork ts checked as not needed
|
|
config.plugins.delete('ForkTsCheckerWebpackPlugin');
|
|
|
|
// explicitly define mainFields to make sure ngcc compiles as es2015 (module field)
|
|
// instead of umd (main field).
|
|
config.resolve.mainFields.add('module').add('main');
|
|
|
|
config.module
|
|
.rule('angular')
|
|
.test(/(?:\.ngfactory.js|\.ngstyle\.js|\.ts)$/)
|
|
.use('@ngtools/webpack')
|
|
.loader('@ngtools/webpack');
|
|
|
|
config.module
|
|
.rule('@angular/core')
|
|
.test(/[\/\\]@angular[\/\\]core[\/\\].+\.js$/)
|
|
.parser({ system: true });
|
|
|
|
// set up html
|
|
config.module
|
|
.rule('html')
|
|
.test(/\.html$/)
|
|
.use('raw-loader')
|
|
.loader('raw-loader');
|
|
|
|
// exclude component css files from the normal css rule
|
|
config.module
|
|
.rule('css')
|
|
.include.add(resolve(getEntryDirPath(), 'app.css'))
|
|
.add(resolve(getEntryDirPath(), `app.${platform}.css`))
|
|
.add(/node_modules/);
|
|
|
|
// and instead use raw-loader, since that's what angular expects
|
|
config.module
|
|
.rule('css|component')
|
|
.exclude.add(resolve(getEntryDirPath(), 'app.css'))
|
|
.add(resolve(getEntryDirPath(), `app.${platform}.css`))
|
|
.add(/node_modules/)
|
|
.end()
|
|
.test(/\.css$/)
|
|
.use('raw-loader')
|
|
.loader('raw-loader');
|
|
|
|
// get base postCSS options
|
|
const postCSSOptions = config.module
|
|
.rule('scss')
|
|
.uses.get('postcss-loader')
|
|
.get('options');
|
|
|
|
// exclude component css files from the normal css rule
|
|
config.module
|
|
.rule('scss')
|
|
.include.add(resolve(getEntryDirPath(), 'app.scss'))
|
|
.add(resolve(getEntryDirPath(), `app.${platform}.scss`))
|
|
.add(/node_modules/);
|
|
|
|
// and instead use raw-loader, since that's what angular expects
|
|
config.module
|
|
.rule('scss|component')
|
|
.exclude.add(resolve(getEntryDirPath(), 'app.css'))
|
|
.add(resolve(getEntryDirPath(), `app.${platform}.css`))
|
|
.add(/node_modules/)
|
|
.end()
|
|
.test(/\.scss$/)
|
|
.use('raw-loader')
|
|
.loader('raw-loader')
|
|
.end()
|
|
.use('postcss-loader')
|
|
.loader('postcss-loader')
|
|
.options(postCSSOptions)
|
|
.end()
|
|
.use('sass-loader')
|
|
.loader('sass-loader');
|
|
|
|
const angularCompilerPlugin = getAngularCompilerPlugin();
|
|
if (angularCompilerPlugin) {
|
|
config.plugin('AngularCompilerPlugin').use(angularCompilerPlugin, [
|
|
{
|
|
tsConfigPath,
|
|
mainPath: getEntryPath(),
|
|
// disable type checking in a forked process - it ignores
|
|
// the hostReplacementPaths and prints errors about
|
|
// platform suffixed files, even though they are
|
|
// working as expected.
|
|
forkTypeChecker: false,
|
|
hostReplacementPaths(path: string) {
|
|
const ext = extname(path);
|
|
const platformExt = `.${platform}${ext}`;
|
|
|
|
// already includes a platform specific extension - ignore
|
|
if (path.includes(platformExt)) {
|
|
return path;
|
|
}
|
|
|
|
const platformPath = path.replace(ext, platformExt);
|
|
// check if the same file exists with a platform suffix and return if it does.
|
|
if (existsSync(platformPath)) {
|
|
// console.log(`[hostReplacementPaths] resolving "${path}" to "${platformPath}"`);
|
|
return platformPath;
|
|
}
|
|
|
|
// just return the original path otherwise
|
|
return path;
|
|
},
|
|
platformTransformers: [require('../transformers/NativeClass').default],
|
|
},
|
|
]);
|
|
}
|
|
|
|
const angularWebpackPlugin = getAngularWebpackPlugin();
|
|
if (angularWebpackPlugin) {
|
|
// angular no longer supports transformers.
|
|
// so we patch their method until they do
|
|
// https://github.com/angular/angular-cli/pull/21046
|
|
const originalCreateFileEmitter =
|
|
angularWebpackPlugin.prototype.createFileEmitter;
|
|
angularWebpackPlugin.prototype.createFileEmitter = function (
|
|
...args: any[]
|
|
) {
|
|
let transformers = args[1] || {};
|
|
if (!transformers.before) {
|
|
transformers.before = [];
|
|
}
|
|
transformers.before.push(require('../transformers/NativeClass').default);
|
|
args[1] = transformers;
|
|
return originalCreateFileEmitter.apply(this, args);
|
|
};
|
|
config.plugin('AngularWebpackPlugin').use(angularWebpackPlugin, [
|
|
{
|
|
tsconfig: tsConfigPath,
|
|
directTemplateLoading: false,
|
|
},
|
|
]);
|
|
|
|
config.when(env.hmr, (config) => {
|
|
config.module
|
|
.rule('angular-hmr')
|
|
.enforce('post')
|
|
.test(getEntryPath())
|
|
.use('angular-hot-loader')
|
|
.loader('angular-hot-loader');
|
|
});
|
|
}
|
|
|
|
// look for platform specific polyfills first
|
|
// falling back to independent polyfills
|
|
const polyfillsPath = [
|
|
resolve(getEntryDirPath(), `polyfills.${platform}.ts`),
|
|
resolve(getEntryDirPath(), `polyfills.ts`),
|
|
].find((path) => existsSync(path));
|
|
|
|
if (polyfillsPath) {
|
|
const paths = config.entry('bundle').values();
|
|
|
|
// replace globals with the polyfills file which
|
|
// should handle loading the correct globals
|
|
// and any additional polyfills required.
|
|
if (paths.includes('@nativescript/core/globals/index.js')) {
|
|
paths[
|
|
paths.indexOf('@nativescript/core/globals/index.js')
|
|
] = polyfillsPath;
|
|
|
|
// replace paths with the update paths
|
|
config.entry('bundle').clear().merge(paths);
|
|
}
|
|
}
|
|
|
|
// Filter common undesirable warnings
|
|
config.set(
|
|
'ignoreWarnings',
|
|
(config.get('ignoreWarnings') ?? []).concat([
|
|
/**
|
|
* This rule hides
|
|
* +-----------------------------------------------------------------------------------------+
|
|
* | WARNING in Zone.js does not support native async/await in ES2017+. |
|
|
* | These blocks are not intercepted by zone.js and will not triggering change detection. |
|
|
* | See: https://github.com/angular/zone.js/pull/1140 for more information. |
|
|
* +-----------------------------------------------------------------------------------------+
|
|
*/
|
|
/Zone\.js does not support native async\/await/,
|
|
/**
|
|
* This rule hides
|
|
* +-----------------------------------------------------------------------------------------+
|
|
* | WARNING in environment.*.ts is part of the TypeScript compilation but it's unused. |
|
|
* | Add only entry points to the 'files' or 'include' properties in your tsconfig. |
|
|
* +-----------------------------------------------------------------------------------------+
|
|
*/
|
|
/environment(\.(\w+))?\.ts is part of the TypeScript compilation but it's unused/,
|
|
// Additional rules to suppress warnings that are safe to ignore
|
|
{
|
|
module: /@angular\/core\/(__ivy_ngcc__\/)?fesm2015\/core.js/,
|
|
message: /Critical dependency: the request of a dependency is an expression/,
|
|
},
|
|
/core\/profiling/,
|
|
/core\/ui\/styling/,
|
|
])
|
|
);
|
|
|
|
return config;
|
|
}
|
|
|
|
function getAngularCompilerPlugin(): any {
|
|
const { AngularCompilerPlugin } = require('@ngtools/webpack');
|
|
return AngularCompilerPlugin;
|
|
}
|
|
|
|
function getAngularWebpackPlugin(): any {
|
|
const { AngularWebpackPlugin } = require('@ngtools/webpack');
|
|
return AngularWebpackPlugin;
|
|
}
|