一种自定义 Angular-cli 6.x/7.x 默认 webpack 配置的方法
栏目: JavaScript · 发布时间: 7年前
内容简介:当前对于
Angular-cli 通过 angular.json 实现构建配置,对于复杂配置需求的支持,可以通过 ng eject 输出 webpack 的配置文件,然后自定义 webpack 来达到目的。
当前对于 Angular 6.x/7.x 的项目, Angular-cli 需采用 6.x/7.x 版本,而这些版本不支持 ng eject 命令,于是希望自定义 webpack 配置实现更多复杂需求就无法下手。
1 自定义 Angular-cli 7.x 默认 webpack 的方案思路
由于 Angular-cli 内部是封装 webpack 来实现的,如果我们能够 hacker 一下,在其 webpack 配置封装过程中注入自定义配置,就也可以实现自定义需求。
按照这个思路,通过翻阅 Angular-cli 的源码,得到如下注入方法。该注入方法采用的 angular 相关 工具 链各版本为:
{
"@angular-devkit/build-angular": "0.10.4",
"@angular/cli": "7.0.4"
}
2 新建注入代码的脚本
新建注入代码的脚本 scripts/insert-to-cli-webpack.js ,内容参考:
const chalk = require('chalk');
const fs = require('fs');
const path = require('path');
const rootDir = path.resolve(__dirname, '../');
const buildNgSrcPathList = {
browser: path.resolve(__dirname, '../node_modules/@angular-devkit/build-angular/src/browser/index.js'),
karma: path.resolve(__dirname, '../node_modules/@angular-devkit/build-angular/src/karma/index.js'),
server: path.resolve(__dirname, '../node_modules/@angular-devkit/build-angular/src/server/index.js'),
};
const webpackCliPath = path.resolve(__dirname, '../config/webpack-cli-inject.js').replace(/\\/g, '\\\\');
const findStr = 'webpackMerge(webpackConfigs)';
try {
Object.keys(buildNgSrcPathList).forEach(type => {
const filePath = buildNgSrcPathList[type];
const filePathShort = filePath.replace(rootDir, '');
const replaceStr = `require('${webpackCliPath}')(webpackMerge(webpackConfigs), wco, '${type}')`;
const configText = fs.readFileSync(filePath, 'utf-8');
if (configText.includes(replaceStr)) {
return;
}
if (!configText.includes(findStr)) {
console.log(chalk.red.bold(`文件 ${chalk.yellow.bold(filePathShort)} 中未发现可替换的字符串: ${findStr}`));
return;
}
console.log(chalk.yellow.bold(` Inserting to: `), chalk.yellow(filePathShort));
const output = configText.replace(findStr, replaceStr);
fs.writeFileSync(filePath, output);
});
console.log(chalk.green.bold(' well done!'));
} catch(err) {
console.log(err);
}
3 新建自定义的 webpack 配置文件
如文件名为 config/webpack.cli-inject.js ,内容参考:
const webpackMerge = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const pkg = require('../package.json');
const isProd = ENV === 'prod' || ENV === 'production';
module.exports = (commonConfig, wco, cfgType) => {
const customCfg = {
module: {
rules: [
{
test: /\.pug$/,
use: [
'raw-loader',
{
loader: 'pug-html-loader',
options: {
doctype: 'html'
}
}
]
},
// {
// test: /\.css$/,
// use: ['to-string-loader', { loader: 'css-loader', options: { url: false } }]
// },
{
test: /\.less$/,
use: [ 'style-loader', 'css-loader', 'sprites-loader', 'less-loader' ]
},
]
},
plugins: [
/*
* See: https://github.com/ampedandwired/html-webpack-plugin
*/
new HtmlWebpackPlugin({
pkg: pkg,
// ----以上为自定义参数,用于模板中调用----
xhtml: true,
template: 'src/index.html',
filename: 'index.html',
chunksSortMode: function(a, b) {
const entryPoints = ['inline', 'polyfills', 'sw-register', 'styles', 'vendor', 'main'];
return entryPoints.indexOf(a.names[0]) - entryPoints.indexOf(b.names[0]);
},
inject: 'body',
minify: isProd
? {
caseSensitive: true,
collapseWhitespace: true,
keepClosingSlash: true
}
: false
}),
],
/**
* Disable performance hints
* See: https://github.com/a-tarasyuk/rr-boilerplate/blob/master/webpack/dev.config.babel.js#L41
*/
// performance: {
// hints: false
// },
// devtool: 'inline-cheap-source-map'
};
// 过滤一些默认的规则,使用自定义的
commonConfig.module.rules = commonConfig.module.rules.filter(rule => {
if (rule.test) {
// 过滤 html 的解析
if (rule.test.test('index.html') && rule.loader === 'raw-loader') {
return false;
}
// // 过滤 less 的解析
if (rule.test.test('index.less')) {
return false;
}
}
return true;
});
const mergedCfg = webpackMerge([commonConfig, customCfg]);
// console.log(cfgType, wco);
// console.log(mergedCfg.module.rules)
return mergedCfg;
};
如上内容示例,我们自定义了如下的 webpack 配置功能:
pug HtmlWebpackPlugin css sprites
注意两点:
- 默认对
html文件的解析 loader 必须屏蔽,否则模板会全部解析为字符串,ejs 语法不会生效; -
less-loader当前不支持less 3.x版本,应当安装less^2.7.x。angular-cli 内部是采用postcss实现的 less 编译。
4 在 package.json 配置 postinstall 钩子
在每次执行 npm install 或 yarn install 后,立即执行 node scripts/insert-to-cli-webpack.js ,即可实现自定义 webpack 配置的需求。
我们可以在 package.json 中配置执行注入脚本的命令 webpack.inject ,示例参考:
"scripts": {
"postinstall": "npm run webpack.inject",
"webpack.inject": "node scripts/insert-to-cli-webpack.js"
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Echo系列教程 — 定制篇6:自定义 Server 相关,替换或扩展默认的 Server
- springboot 默认日志配置
- HDFS副本设置——默认3
- WPF 绑定的默认模式
- StackOverflow转向默认使用HTTPS
- Spring解密 - 默认标签的解析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。