-
Notifications
You must be signed in to change notification settings - Fork 27
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
@ngtools/webpack #4
Comments
I have not tested it with rules: [
{
test: /\.ts$/,
loader: ['@ngtools/webpack', 'ifdef-loader?${q}']
}
] |
hi @nippur72 , It looks like it is working with ngtools/webpack. I run across a strange issue with lazy loaded module. ngtools/webpack compile typescripts with AoT (Angular). For AoT to work, codes should be statically analyzable. Will the code below able to pick up by ngtool/webpack?
@NgModule({
|
yes it will feed the code with
when the flag Going a bit off-topic, if your scenario is a simple PRODUCTION/DEVELOPMENT environment you might not need Example: serManagementModule,
PortfolioBookNg2Module,
PRODUCTION ? RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) : RouterModule.forRoot(routes),
UpgradeModule and then use this plugin in webpack: const uglify = new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
global_defs: {
PRODUCTION: true /* or false */,
}
}
}); |
hI @nippur72 , It will not work for AoT build though. I get the following error: |
I am not sure, but if you are using TypeScript maybe you need to declare the // somewhere in a .ts
declare global {
export var PRODUCTION;
export var DEVELOPMENT;
} Also, you need to manually set the above two variables when not using uglify-js (that is, during DEVELOPMENT): if(PRODUCTION === undefined) {
window["PRODUCTION"] = false;
window["DEVELOPMENT"] = true;
}
// note that the above code will erased in production |
This was working for me for Tried to update this lib to 2.x cause I was still on 1.x and its not working either. This is how im doing it now const ifDefOpts = querystring.encode({
DEV: isDevBuild,
});
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/, use: isDevBuild
? ["awesome-typescript-loader?silent=true", "angular2-template-loader", `ifdef-loader?${ifDefOpts}`]
: ["@ngtools/webpack", `ifdef-loader?${ifDefOpts}`] |
@stephenlautier you can use the echo-loader to debug exactly what is happening in the chain of your loaders. For instance you can put it after
(The |
@nippur72 thanks for the info! im not a webpack guru so it definitely helps 👍 i will try and give that a shot |
hmm.. its very strange, i tested out with @nippur72 and the code is not there, so not sure how its giving an error 😕 sourceimport "reflect-metadata";
import "zone.js";
import "hammerjs";
import { enableProdMode } from "@angular/core";
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
// todo: get this back working
/// #if DEV
// import "./app/app-light.theme.scss";
import "./app/app-dark.theme.scss";
/// #endif
import { AppModule } from "./app/app.module.browser"; dump afterdump: boot.browser.ts
*************
import "reflect-metadata";
import "zone.js";
import "hammerjs";
import { enableProdMode } from "@angular/core";
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
// todo: get this back working
///////////
///////////////////////////////////////
///////////////////////////////////
//////////
import { AppModule } from "./app/app.module.browser"; so it is actually getting removed, not sure then why/how its blowing and from where its resolving it, this is the error ERROR in ./ClientApp/app/app-dark.theme.scss
Module parse failed: Unexpected character '@' (1:0)
You may need an appropriate loader to handle this file type.
| @import "themes/dark.theme";
| @import "settings";
@ ./ClientApp/boot.browser.ts 8:0-35 and if i comment out manually the scss import, it works |
For some reason webpack is picking the unprocessed |
Sure, this is all of it, and it happens when run prod mode, so const path = require("path");
const fs = require("fs");
const querystring = require("querystring");
const chalk = require("chalk");
const webpack = require("webpack");
const merge = require("webpack-merge");
const AngularCompilerPlugin = require("@ngtools/webpack").AngularCompilerPlugin;
const CheckerPlugin = require("awesome-typescript-loader").CheckerPlugin;
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = (env) => {
const isDevBuild = !(env && env.prod);
const srcRoot = "ClientApp";
console.log(chalk`{cyan.bold Build environment isDev: ${isDevBuild}}`);
const ifDefOpts = querystring.encode({
DEV: isDevBuild,
});
const extractSass = new ExtractTextPlugin({
filename: "[name].css",
disable: isDevBuild
});
const sassConfig = extractSass.extract({
use: [{
loader: "css-loader", // translates CSS into CommonJS
options: {
minimize: !isDevBuild
}
}, {
loader: "sass-loader", // compiles Sass to CSS
options: {
includePaths: [
`./${srcRoot}/assets/styles`,
`./${srcRoot}/libraries`
]
}
}],
// use style-loader in development
fallback: "style-loader" // creates style nodes from JS strings
});
// Configuration in common to both client-side and server-side bundles
const sharedConfig = {
stats: { modules: false },
context: __dirname,
resolve: { extensions: [".js", ".ts"] },
output: {
filename: "[name].js",
publicPath: "dist/" // Webpack dev middleware, if enabled, handles requests for this URL prefix
},
module: {
rules: [
{
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/, use: isDevBuild
? ["awesome-typescript-loader?silent=true", "angular2-template-loader", `ifdef-loader?${ifDefOpts}`]
: ["@ngtools/webpack", `ifdef-loader?${ifDefOpts}`]
},
{ test: /\.html$/, use: "html-loader?minimize=false" },
{ test: /\.css$/, use: ["to-string-loader", isDevBuild ? "css-loader" : "css-loader?minimize"] },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: "url-loader?limit=1000000" }
].concat(isDevBuild ? [
// Plugins that apply in development builds only
{ test: /\.scss$/, use: sassConfig },
{ test: /\.js$/, use: ["source-map-loader"], enforce: "pre" }
] : [])
},
plugins: [
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || isDevBuild ? "development" : "production")
}),
new CheckerPlugin(),
extractSass
]
};
// Configuration for client-side bundle suitable for running in browsers
const clientBundleOutputDir = "./wwwroot/dist";
const clientBundleConfig = merge(sharedConfig, {
entry: { "main-client": `./${srcRoot}/boot.browser.ts` },
output: { path: path.join(__dirname, clientBundleOutputDir) },
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require("./wwwroot/dist/vendor-manifest.json")
})
].concat(isDevBuild ? [
// Plugins that apply in development builds only
new webpack.SourceMapDevToolPlugin({
filename: "[file].map", // Remove this line if you prefer inline source maps
moduleFilenameTemplate: path.relative(clientBundleOutputDir, "[resourcePath]") // Point sourcemap entries to the original file locations on disk
})
] : [
// Plugins that apply in production builds only
new webpack.optimize.UglifyJsPlugin(),
new AngularCompilerPlugin({
tsConfigPath: "./tsconfig.browser.json",
entryModule: path.join(__dirname, "ClientApp/app/app.module.browser#AppModule"),
compilerOptions: {
noUnusedParameters: false,
},
})
])
});
let sassBundleConfig;
if (!isDevBuild) {
const themes = getThemes(`./${srcRoot}/app`);
sassBundleConfig = {
stats: { modules: false },
context: __dirname,
output: {
filename: "[name].css",
path: path.join(__dirname, clientBundleOutputDir),
publicPath: "/dist/" // Webpack dev middleware, if enabled, handles requests for this URL prefix
},
entry: themes,
module: {
rules: [
{ test: /\.scss$/, use: sassConfig }
]
},
plugins: [extractSass]
};
}
// Configuration for server-side (prerendering) bundle suitable for running in Node
let serverBundleConfig = merge(sharedConfig, {
entry: { "main-server": `./${srcRoot}/boot.server.ts` },
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require(`./${srcRoot}/dist/vendor-manifest.json`),
sourceType: "commonjs2",
name: "./vendor"
})
].concat(isDevBuild ? [] : [
// Plugins that apply in production builds only
new AngularCompilerPlugin({
tsConfigPath: "./tsconfig.server.json",
entryModule: path.join(__dirname, "ClientApp/app/app.module.server#AppModule"),
compilerOptions: {
noUnusedParameters: false,
}
})
]),
output: {
libraryTarget: "commonjs",
path: path.join(__dirname, `./${srcRoot}/dist`)
},
target: "node",
devtool: "inline-source-map"
});
if (isDevBuild) {
// todo: try to change back to "main" only, as it reduces file size drastically - with it @odin pkgs are being loaded twice duplicated (umd/esm).
serverBundleConfig = merge(serverBundleConfig, {
resolve: { mainFields: ["main"] },
});
}
return [
clientBundleConfig,
serverBundleConfig,
sassBundleConfig,
].filter(x => x);
};
// todo: move to build-tools
function getThemes(themePath) {
let themes = {};
fs.readdirSync(themePath).forEach(fileName => {
const fileNameWithPath = path.resolve(themePath, fileName);
const stat = fs.lstatSync(fileNameWithPath);
if (stat.isDirectory()) return;
if (!/\.theme\.scss$/.test(fileName)) return;
const nameWithoutExt = path.basename(fileName, ".scss");
themes[nameWithoutExt] = fileNameWithPath;
});
return themes;
}; |
sorry I was not able to locate the issue, I tried to replicate your env but got lost along the way 😞 If the problem is in any of the loaders you can debug which one is actually being triggered, again with the { test: /\.html$/, use: ["html-loader?minimize=false","echo-loader?msg=html_loader"] }, With this method I once discovered a file being picked twice. |
thanks for trying! if i get some time I have a simpler project which is similar because that's based on a template, I will update it and get it with the same issue, and you can try there if you'd like |
According to this bug, I had some luck reversing the order: i.e. running Input file: let AuthServiceProvider: Provider = AuthService;
/// #if MODE === 'mock'
console.log('using mock AuthService');
AuthServiceProvider = require('./auth.service.mock').MockAuthServiceProvider;
/// #endif webpack config: {
rules: [ {
test: /\.ts$/,
use: [
{ loader: 'echo-loader?msg=dump' }, // runs last
{ loader: '@ngtools/webpack' },
{ loader: 'ifdef-loader' }, // runs first
]
}],
} Output: var AuthServiceProvider = AuthService;
/// #if MODE === 'mock' <--- WRONG: the if block was not evaluated
console.log('using mock AuthService');
AuthServiceProvider = require('./auth.service.mock').MockAuthServiceProvider;
/// #endif When I reverse the order of false var AuthServiceProvider = AuthService;
///////////////////////
//////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
////////// true var AuthServiceProvider = AuthService;
///////////////////////
console.log('using mock AuthService');
AuthServiceProvider = require('./auth.service.mock').MockAuthServiceProvider;
////////// But this approach is fragile since it relies on an implementation detail of |
@mamacdon thanks i managed to get this working. Just another issue we encountered is the following This wasnt working /// #if DEV
import "./app/app-dark.theme.scss";
/// #endif
import { AppModule } from "./app/app.module.browser"; This works import { AppModule } from "./app/app.module.browser";
/// #if DEV
import "./app/app-dark.theme.scss";
/// #endif For some reason the first one was stripping the |
Hi,
Instead of ts-loader, I have use ngtools/webpack which compile and perform AoT. does ifdef-loader work with ngtools/webpack?
cheers,
Khoa
The text was updated successfully, but these errors were encountered: