一种自定义 Angular-cli 6.x/7.x 默认 webpack 配置的方法
栏目: JavaScript · 发布时间: 6年前
内容简介:当前对于
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解密 - 默认标签的解析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。