gulp常用插件之gulp-inject使用
更多gulp常用插件使用请访问:gulp常用插件汇总
gulp-inject这个插件的作用与wiredep类似,不同的是可以自己任意指定需要插入文件的列表。它同样是利用注释来寻找插入的位置。获取源文件流,将每个文件转换为字符串,并将每个转换后的字符串注入目标流文件中的占位符。
同样是利用注释来寻找插入的位置,它识别的默认注释为,但更加智能:
- 支持各种模板语言:可以根据gulp.src指定的源文件自动识别注释和插入内容,除了支持HTML外,还支持jade、haml等。若源为jade文件,则识别的注释为//- inject:js,插入的内容为:script(src=".js")。
- 配置非常灵活:
name
:默认识别的注释标签格式为,这里的name
默认值就是“inject”,而ext
的默认值是要插入的文件的扩展名。那么name
属性可配置意味着可以添加自定义的插入区块,如,这个标签可以只插入生产环境需要包含的JS文件。starttag
和endtag
:支持自定义需要识别的注释内容。addPrefix
和addSuffix
:支持在插入文件的路径上自定义前缀、后缀。relative
:指定插入文件的路径是否为相对路径。ingorePath
:指定插入文件的路径前面会忽略掉指定的路径。read
:这个参数通常给false
,不需要真正的去读取文件。
安装
一键安装不多解释
npm install --save-dev gulp-inject
使用
目标文件src/index.html
:
每对注释都是注入占位符
<!DOCTYPE html>
<html>
<head>
<title>My index</title>
<!-- inject:css -->
<!-- endinject -->
</head>
<body>
<!-- inject:js -->
<!-- endinject -->
</body>
</html>
在gulpfile.js
:
var gulp = require('gulp');
var inject = require('gulp-inject');
gulp.task('index', function () {
var target = gulp.src('./src/index.html');
//不需要读取文件(这会加快速度),我们只需要查看它们的路径:
var sources = gulp.src(['./src/**/*.js', './src/**/*.css'], {read: false});
return target.pipe(inject(sources))
.pipe(gulp.dest('./src'));
});
执行gulp命令之后index.html:
<!DOCTYPE html>
<html>
<head>
<title>My index</title>
<!-- inject:css -->
<link rel="stylesheet" href="/src/style1.css">
<link rel="stylesheet" href="/src/style2.css">
<!-- endinject -->
</head>
<body>
<!-- inject:js -->
<script src="/src/lib1.js"></script>
<script src="/src/lib2.js"></script>
<!-- endinject -->
</body>
</html>
更多例子:
相对于目标文件注入文件
默认情况下,注入的文件路径是相对于每个源文件的路径cwd
。如果options.relative
设置为true
,则每个注入的路径将相对于每个目标文件的目录。
项目结构:
└── src
├── module
│ ├── module.js
│ └── module.html
└── app
├── main.js
└── index.html
src/app/index.html:
<!DOCTYPE html>
<html>
<head>
<title>My Index</title>
</head>
<body>
<h1>Home</h1>
<!-- inject:js -->
<!-- endinject -->
</body>
</html>
src/module/module.html:
<!DOCTYPE html>
<html>
<head>
<title>Module</title>
</head>
<body>
<h1>Module</h1>
<!-- inject:js -->
<!-- endinject -->
</body>
</html>
gulpfile.js:
var inject = require('gulp-inject');
gulp.src('./src/**/*.html')
.pipe(inject(gulp.src('./src/**/*.js', {read: false}), {relative: true}))
.pipe(gulp.dest('./src'));
结果src/app/index.html:
<!DOCTYPE html>
<html>
<head>
<title>My Index</title>
</head>
<body>
<h1>Home</h1>
<!-- inject:js -->
<script src="main.js"></script>
<script src="../module/module.js"></script>
<!-- endinject -->
</body>
</html>
结果src/module/module.html:
<!DOCTYPE html>
<html>
<head>
<title>Module</title>
</head>
<body>
<h1>Home</h1>
<!-- inject:js -->
<script src="../app/main.js"></script>
<script src="module.js"></script>
<!-- endinject -->
</body>
</html>
从多个源流注入文件
此示例演示如何将来自多个不同流的文件注入到同一注入占位符。
安装event-stream方式:npm install --save-dev event-stream
并使用其merge功能。
代码:
var es = require('event-stream'),
inject = require('gulp-inject'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify');
// 连接供应商脚本
var vendorStream = gulp.src(['./src/vendors/*.js'])
.pipe(concat('vendors.js'))
.pipe(gulp.dest('./dist'));
// 连接和缩小应用程序源
var appStream = gulp.src(['./src/app/*.js'])
.pipe(concat('app.js'))
.pipe(uglify())
.pipe(gulp.dest('./dist'));
gulp.src('./src/index.html')
.pipe(inject(es.merge(vendorStream, appStream)))
.pipe(gulp.dest('./dist'));
订单重要时有多个来源
使用stream-series。
var series = require('stream-series'),
inject = require('gulp-inject');
var vendorStream = gulp.src(['./src/vendors/*.js'], {read: false});
var appStream = gulp.src(['./src/app/*.js'], {read: false});
gulp.src('./src/index.html')
.pipe(inject(series(vendorStream, appStream))) //这将始终在应用程序文件之前注入供应商文件
.pipe(gulp.dest('./dist'));
注入一些文件到<head>
一些成<body>
方法1:使用gulp-inject的starttag选项。
gulpfile.js:
var inject = require('gulp-inject');
gulp.src('./src/index.html')
.pipe(inject(gulp.src('./src/importantFile.js', {read: false}), {starttag: '<!-- inject:head:{{ext}} -->'}))
.pipe(inject(gulp.src(['./src/*.js', '!./src/importantFile.js'], {read: false})))
.pipe(gulp.dest('./dist'));
并在您的./src/index.html:
<!DOCTYPE html>
<html>
<head>
<title>My index</title>
<!-- inject:head:js -->
<!-- only importantFile.js will be injected here -->
<!-- endinject -->
</head>
<body>
<!-- inject:js -->
<!-- the rest of the *.js files will be injected here -->
<!-- endinject -->
</body>
</html>
方法2:使用gulp-inject的name选项。
gulpfile.js:
var inject = require('gulp-inject');
gulp.src('./src/index.html')
.pipe(inject(gulp.src('./src/importantFile.js', {read: false}), {name: 'head'}))
.pipe(inject(gulp.src(['./src/*.js', '!./src/importantFile.js'], {read: false})))
.pipe(gulp.dest('./dist'));
并在您的./src/index.html:
<!DOCTYPE html>
<html>
<head>
<title>My index</title>
<!-- head:js -->
<!-- only importantFile.js will be injected here -->
<!-- endinject -->
</head>
<body>
<!-- inject:js -->
<!-- the rest of the *.js files will be injected here -->
<!-- endinject -->
</body>
</html>
注入所有文件进行开发
如果您将Bower用于前端依赖项,我建议也使用main-bower-files和注入它们。
gulpfile.js:
var bowerFiles = require('main-bower-files'),
inject = require('gulp-inject'),
stylus = require('gulp-stylus'),
es = require('event-stream');
var cssFiles = gulp.src('./src/**/*.styl')
.pipe(stylus())
.pipe(gulp.dest('./build'));
gulp.src('./src/index.html')
.pipe(inject(gulp.src(bowerFiles(), {read: false}), {name: 'bower'}))
.pipe(inject(es.merge(
cssFiles,
gulp.src('./src/app/**/*.js', {read: false})
)))
.pipe(gulp.dest('./build'));
src/index.html:
<!DOCTYPE html>
<html>
<head>
<title>My index</title>
<!-- bower:css -->
<!-- bower installed css files will go here... -->
<!-- endinject -->
<!-- inject:css -->
<!-- built css files will go here... -->
<!-- endinject -->
</head>
<body>
<!-- bower:js -->
<!-- bower installed scripts will go here... -->
<!-- endinject -->
<!-- inject:js -->
<!-- app scripts will go here... -->
<!-- endinject -->
</body>
</html>
请注意,请记住在服务器上挂载
./bower_components
,./build
并将其./src/app
作为静态资源以使其正常工作。
注入一个json文件
您可以gulp-inject
使用transformfunction
选项进一步定制,例如,将文件注入json
文件。
代码如下:
gulp.src('./files.json')
.pipe(inject(gulp.src(['./src/*.js', './src/*.css', './src/*.html'], {read: false}), {
starttag: '"{{ext}}": [',
endtag: ']',
transform: function (filepath, file, i, length) {
return ' "' + filepath + '"' + (i + 1 < length ? ',' : '');
}
}))
.pipe(gulp.dest('./'));
初始内容files.json
:
{
“ js ”:[
],
“ css ”:[
],
“ html ”:[
]
}
transform
使用默认回退的自定义功能进行注入
该默认transform功能可使用例如作为默认的备用。
在此处用于将Word文档作为<a>
以下标记注入:
index.html:
<!DOCTYPE html>
<html>
<head>
<title>My documents</title>
</head>
<body>
<h1>Documents</h1>
<ul>
<!-- inject:docx -->
<!-- endinject -->
</ul>
<!-- inject:js -->
<!-- endinject -->
</body>
</html>
gulpfile.js:
var inject = require('gulp-inject');
gulp.src('./index.html')
.pipe(inject(
gulp.src(['./*.js', './docs/*.docx'], {read: false}), {
transform: function (filepath) {
if (filepath.slice(-5) === '.docx') {
return '<li><a href="' + filepath + '">' + filepath + '</a></li>';
}
// Use the default transform as fallback:
return inject.transform.apply(inject.transform, arguments);
}
}
))
.pipe(gulp.dest('./'));
运行结束的index.html:
<!DOCTYPE html>
<html>
<head>
<title>My documents</title>
</head>
<body>
<h1>Documents</h1>
<ul>
<!-- inject:docx -->
<li><a href="/docs/document1.docx"></a></li>
<li><a href="/docs/document2.docx"></a></li>
<!-- endinject -->
</ul>
<!-- inject:js -->
<script src="/lib1.js"></script>
<script src="/lib2.js"></script>
<!-- endinject -->
</body>
</html>
将dist文件注入bower.json的主要部分
代码如下:
gulp.src('./bower.json')
.pipe(inject(gulp.src(['./dist/app.min.js', './dist/app.min.css'], {read: false}), {
starttag: '"main": [',
endtag: ']',
transform: function (filepath, file, i, length) {
return ' "' + filepath + '"' + (i + 1 < length ? ',' : '');
}
}))
.pipe(gulp.dest('./'));
将所有javascript文件注入到业力配置文件中
代码如下:
gulp.src('./karma.conf.js')
.pipe(inject(gulp.src(['./src/**/*.js'], {read: false}), {
starttag: 'files: [',
endtag: ']',
transform: function (filepath, file, i, length) {
return ' "' + filepath + '"' + (i + 1 < length ? ',' : '');
}
}))
.pipe(gulp.dest('./'));
注入文件内容
为了注入文件内容,您必须提供自定义transform
功能,该功能将以字符串形式返回文件内容。在这种情况下,您还必须省略{read: false}
选项gulp.src
。以下示例显示了如何将html
局部内容注入到head
中index.html
:
gulp.src('./src/index.html')
.pipe(inject(gulp.src(['./src/partials/head/*.html']), {
starttag: '<!-- inject:head:{{ext}} -->',
transform: function (filePath, file) {
// return file contents as string
return file.contents.toString('utf8')
}
}))
.pipe(gulp.dest('./dest'));
./src/index.html
:
<!DOCTYPE html>
<html>
<head>
<title>My index</title>
<!-- inject:head:html -->
<!-- contents of html partials will be injected here -->
<!-- endinject -->
</head>
<body>
</body>
</html>
根据文件路径注入文件内容
为了根据文件路径注入文件,您必须提供自定义starttag
,其中包括{{path}}
。另外,为了注入文件内容包括transform
函数,该函数将以字符串形式返回文件内容。在这种情况下,您还必须省略{read: false}
选项gulp.src
。路径可以是绝对路径,也可以是相对路径,在这种情况下,应将[ options.relative]
设置为true
。以下示例显示了如何将html
局部内容注入到index.html
:
代码如下:
gulp.src('./src/index.html')
.pipe(inject(gulp.src(['./src/partials/head/*.html']), {
starttag: '<!-- inject:{{path}} -->',
relative: true,
transform: function (filePath, file) {
// return file contents as string
return file.contents.toString('utf8')
}
}))
.pipe(gulp.dest('./dest'));
./src/index.html
:
<!DOCTYPE html>
<html>
<head>
<title>My index</title>
<!-- inject:path/to/your/file.ext -->
<!-- contents of html partials will be injected here -->
<!-- endinject -->
</head>
<body>
</body>
</html>
API
inject(sources, options)
- 参数:
sources
类型:Stream
提供Vinyl File Stream
作为输入inject,请参见上面的示例。 - 参数:
options
类型:Object
options参数详解
options.ignorePath
类型:String
或Array
默认:NULL
应从每个插入的文件路径中删除的一个或多个路径。
这也可以通过cwd
为gulp.src
流设置选项来解决,cwd
在注入之前,每个源文件都会自动从其路径中删除(如果未options.relative
设置为true
,请参见下文)。options.relative
类型:Boolean
默认:false
如果将true
注入文件的路径设置为相对于每个目标文件的路径,则这也意味着cwd
不必从其路径中删除每个源文件。options.addPrefix
类型:String
默认:NULL
应在每个注入的文件路径之前添加路径。
*options.addSuffix
类型:String
默认:NULL
每个注入的文件路径均应添加后缀的路径。options.addRootSlash
类型:Boolean
默认:!options.relative
根斜杠会自动添加到路径('/')的开头,如果设置为,则将其删除false
。options.name
类型:String
默认:"inject"
在下面的默认starttag
和endtag
标记中使用。options.removeTags
类型:Boolean
默认:false
当true
注射文件时,开始和结束标记将被删除。options.empty
类型:Boolean
默认:false
当true
所有没有相应文件的标签将被清空。
警告这可能会导致清空过多的问题。
options.starttag
类型:String |Function(targetExt, sourceExt)
参数(如果有功能):targetExt
: 目标文件的文件扩展名sourceExt
: 源文件的文件扩展名
目的:
用于根据文件扩展名动态设置起始占位符标签。在提供的字符串或从给定函数返回的字符串中,该字符串{{ext}}
将替换为源文件扩展名,例如“ css”,“ js”或“ html”。{{name}}
将由取代options.name
。{{path}}
将被源文件的路径替换(当与[options.relative
] 一起使用时,将允许源文件的相对路径。
默认:
取决于目标文件类型和源文件类型的函数返回:- 以html为目标:
<!-- {{name}}:{{ext}} -->
- haml作为目标:
-# {{name}}:{{ext}}
- 玉为目标:
//- {{name}}:{{ext}}
- 哈巴狗为目标:
//- {{name}}:{{ext}}
- jsx作为目标:
{/* {{name}}:{{ext}} */}
- slm作为目标:
/ {{name}}:{{ext}}
- 少于目标:
/* {{name}}:{{ext}} */
- sass,scss作为目标:
/* {{name}}:{{ext}} */
options.endtag
类型:String |Function(targetExt, sourceExt)
参数(如果有功能):targetExt
: 目标文件的文件扩展名sourceExt
: 源文件的文件扩展名
目的:
用于根据文件扩展名动态设置结尾占位符标签。在提供的字符串或从给定函数返回的字符串中,该字符串{{ext}}
将替换为源文件扩展名,例如“ css”,“ js”或“ html”。{{name}}
将由取代options.name
。{{path}}
将替换为源文件的路径。
默认:
取决于目标文件类型和源文件类型的函数返回:- 以html为目标:
<!-- endinject -->
- haml作为目标:
-# endinject
- 玉为目标:
//- endinject
- 哈巴狗为目标:
//- endinject
- jsx作为目标:
{/* endinject */}
- slm作为目标:
/ endinject
- 少于目标:
/* endinject */
- sass,scss作为目标:
/* endinject */
options.transform
类型:Function(filepath, file, index, length, targetFile)
参数:filepath
:ignorePath
删除addPrefix
并addSuffix
添加了任何的文件的“ unixified”路径file
: 要注入的File对象来自gulp.src
index
: 从0开始的文件索引length
: 当前文件扩展名要注入的文件总数targetFile
: 要注入的目标文件
目的:
用于生成要为每个文件注入的内容。
默认:
取决于目标文件类型和源文件类型的函数返回:注入
html
- CSS文件:
<link rel="stylesheet" href="<filename>.css">
- js文件:
<script src="<filename>.js"></script>
- 咖啡档案:
<script type="text/coffeescript" src="<filename>.coffee"></script>
- html文件:
<link rel="import" href="<filename>.html">
- png文件:
<img src="<filename>.png">
- gif文件:
<img src="<filename>.gif">
- jpg文件:
<img src="<filename>.jpg">
- jpeg文件:
<img src="<filename>.jpeg">
如果
options.selfClosingTag
为,true
则上面的默认转换器将使<link>
和<img>
标签自闭,即分别为:<link ... />
和<img ... />
。注入
jsx
html
与options.selfClosingTag
设置为的上述注入相同true
。注入
jade
- CSS文件:
link(rel="stylesheet", href="<filename>.css")
- js文件:
script(src="<filename>.js")
- 咖啡档案:
script(type="text/coffeescript", src="<filename>.coffee")
- html文件:
link(rel="import", href="<filename>.html")
- png文件:
img(src="<filename>.png")
- gif文件:
img(src="<filename>.gif")
- jpg文件:
img(src="<filename>.jpg")
- jpeg文件:
img(src="<filename>.jpeg")
注入
pug
- CSS文件:
link(rel="stylesheet", href="<filename>.css")
- js文件:
script(src="<filename>.js")
- 咖啡档案:
script(type="text/coffeescript", src="<filename>.coffee")
- html文件:
link(rel="import", href="<filename>.html")
- png文件:
img(src="<filename>.png")
- gif文件:
img(src="<filename>.gif")
- jpg文件:
img(src="<filename>.jpg")
- jpeg文件:
img(src="<filename>.jpeg")
注入
slm
- CSS文件:
link rel="stylesheet" href="<filename>.css"
- js文件:
script src="<filename>.js"
- 咖啡档案:
script type="text/coffeescript" src="<filename>.coffee"
- html文件:
link rel="import" href="<filename>.html"
- png文件:
img src="<filename>.png"
- gif文件:
img src="<filename>.gif"
- jpg文件:
img src="<filename>.jpg"
- jpeg文件:
img src="<filename>.jpeg"
注入
haml
- CSS文件:
%link{rel:"stylesheet", href:"<filename>.css"}
- js文件:
%script{src:"<filename>.js"}
- 咖啡档案:
%script{type:"text/coffeescript", src:"<filename>.coffee"}
- html文件:
%link{rel:"import", href:"<filename>.html"}
- png文件:
%img{src:"<filename>.png"}
- gif文件:
%img{src:"<filename>.gif"}
- jpg文件:
%img{src:"<filename>.jpg"}
- jpeg文件:
%img{src:"<filename>.jpeg"}
注入
less
CSS文件:@import "<filename>.css";
较少的文件:@import "<filename>.less";
注入
scss
CSS文件:@import "<filename>.css";
scss文件:@import "<filename>.scss";
sass文件:@import "<filename>.sass";
注入
sass
CSS文件:@import "<filename>.css"
sass文件:@import "<filename>.sass"
scss文件:@import "<filename>.scss"
options.selfClosingTag
类型:Boolean
默认:false
影响默认options.transform
功能,请参见上文。options.quiet
类型:Boolean
默认:false
通过将其设置为true可以降低详细程度,从而抑制成功注射的记录。inject.transform
默认转换函数在公共API中公开。nject.transform.html
默认的将文件转换为html或其他文件类型的转换函数,而不是jade
、pug
、jsx
、slm
、less
、scss
、sass
或haml
。inject.transform.jade
文件的默认转换功能为jade
inject.transform.pug
文件的默认转换功能为pug
inject.transform.jsx
文件的默认转换功能为jsx
inject.transform.slm
文件的默认转换功能为slm
inject.transform.haml
文件的默认转换功能为haml
inject.transform.less
文件的默认转换功能为less
inject.transform.sass
文件的默认转换功能为sass
inject.transform.scss
文件的默认转换功能为scss
gulp常用插件之gulp-inject使用的更多相关文章
- 精通gulp常用插件
本文主要展示的是gulp常用插件的使用方法和用途,通过对插件的熟练运用达到精通gulp.不定期更新.可以到github上面下载DEMO. github地址:lin-xin/gulp-plugins 匹 ...
- node和gulp实现前端工程自动化(附:gulp常用插件)
/** * 1. LESS编译 压缩 合并 * 2. JS合并 压缩 混淆 * 3. img复制 * 4. html压缩 */ // 在gulpfile中先载入gulp包,因为这个包提供了一些APIv ...
- gulp常用插件之gulp-eslint使用
更多gulp常用插件使用请访问:gulp常用插件汇总 ** gulp-eslint**这是一个用于识别和报告在ECMAScript/JavaScript代码中找到的模式的Gulp插件.. 更多使用文档 ...
- gulp常用插件之gulp-babel使用
更多gulp常用插件使用请访问:gulp常用插件汇总 gulp-babel这是Babel的Gulp插件. 此自述文件适用于gulp-babel v8 + Babel v7检查7.x分支以了解使用Bab ...
- gulp常用插件之gulp-postcss使用
更多gulp常用插件使用请访问:gulp常用插件汇总 ** gulp-postcss**这是一款通过多个插件通过管道传递CSS,但是仅解析一次CSS. 更多使用文档请点击访问gulp-postcss工 ...
- gulp常用插件之cssnano使用
更多gulp常用插件使用请访问:gulp常用插件汇总 cssnano这是一款将你的 CSS 文件做 多方面的的优化,以确保最终生成的文件 对生产环境来说体积是最小的插件. 更多使用文档请点击访问cha ...
- gulp常用插件之pump使用
更多gulp常用插件使用请访问:gulp常用插件汇总 pump这是一款小型节点模块,可将流连接在一起并在其中一个关闭时将其全部销毁. 使用标准source.pipe(dest)源时,如果dest发出关 ...
- gulp常用插件之gulp-notify使用
更多gulp常用插件使用请访问:gulp常用插件汇总 gulp-notify这是一款gulp通知插件. 更多使用文档请点击访问gulp-notify工具官网. 安装 一键安装不多解释 npm inst ...
- gulp常用插件之gulp-beautify使用
更多gulp常用插件使用请访问:gulp常用插件汇总 gulp-beautify这是一款使用js-beautify进行资产美化插件. 更多使用文档请点击访问gulp-beautify工具官网. 安装 ...
随机推荐
- 20200105--python学习第七天
今日内容 深浅拷贝 文件操作 内容回顾及补充 1.内容回顾 计算机基础 编码 语法 if/while/for 数据类型 type/id/range 运算符 2.面试题 a.公司线上的系统用的是什么? ...
- 20200105--python学习数据类型总结
总结 python中的数据类型:整型/布尔类型/字符串/元组/列表/字典/集合 注意:列表,字典,集合都不能作为字典中的key,也不能作为集合中的元素 数据类型: (1)整型 (2)布尔类型:只有两个 ...
- win10配置CUDA+Tensorflow2.0的一些经验
目录 问题描述 安装 tensorflow-cpu-2.0 编译 Nvidia Samples 问题描述 网上已经很多关于配置CUDA的文章,自己这篇文章只是个大致的安装步骤,文章重点是安装和配置的一 ...
- [WPF 自定义控件]自定义一个“传统”的 Validation.ErrorTemplate
1. 什么是Validaion.ErrorTemplate 数据绑定模型允许您将与您Binding的对象相关联ValidationRules. 如果用户输入的值无效,你可能希望在应用程序 用户界面 ( ...
- matlab---设置背景颜色为白色
(1)每次设置figure('color','w');或者figure('color',[1 1 1])或者set(gcf,'color','w'); (2)一次性:在命令行内输入 set(0,'de ...
- C++ char to string 方法
1. 使用string()构造函数方法 //method 1: the constructor of string() char c = 'F'; , c); cout << s ; 2. ...
- Dynamics 365 marketing中添加自定义渠道磁贴
Dynamics 365 marketing中默认的渠道只有Marketing Email和Marketing Activity,想要添加其他渠道必须自定义磁贴,自定义磁贴的步骤如下: 1.创建实体 ...
- 详细讲解Codeforces Round #624 (Div. 3) E. Construct the Binary Tree(构造二叉树)
题意:给定节点数n和所有节点的深度总和d,问能否构造出这样的二叉树.能,则输出“YES”,并且输出n-1个节点的父节点(节点1为根节点). 题解:n个节点构成的二叉树中,完全(满)二叉树的深度总和最小 ...
- O2O外卖玩众包 开放平台难解标准之痛
开放平台难解标准之痛" title="O2O外卖玩众包 开放平台难解标准之痛"> 有一种怪现象一直是国内互联网企业摆脱不了的附骨之疽--不管规模大小,总是削尖了脑 ...
- PMP--2.2 效益管理计划
一.文件背景概述 1. 所需文件/数据 制定效益管理计划需要使用商业论证和需求评估中的数据和信息,例如,成本效益分析数据. 成本效益分析数据是在商业论证和需求评估中得到的,在成本效益分析中已经把 ...