【问题标题】:How can I use a template with a changing value for a grunt-contrib-copy cwd property如何为 grunt-contrib-copy cwd 属性使用具有变化值的模板
【发布时间】:2017-05-18 21:53:40
【问题描述】:

我有一个 grunt 构建,应该执行以下操作:

  • 从某个位置复制项目
  • 从这些复制的文件中加载 package.json 文件并提取版本号
  • 从依赖于该版本号的文件夹中复制项目

我有一个读取版本号的任务:

grunt.task.registerTask(
    "readVersionNumber",
    "Reads a version number",
    function(){
        var versionNumber = grunt.file.readJSON("pathToJson");
        grunt.config.set("versionNumber",versionNumber);
    }
);

(打字而不是复制/粘贴,所以可能有一些小错别字)

我有一个带有 cwd 的复制任务:

"cwd": "//networkPath/<%= versionNumber %>/docs"

但这不起作用...

我有一个非常相似的设置来替换 html / js 文件中的文本并查看 grunt-text-replace.js 文件,它使用 grunt.template.process 将字符串中的模板替换为实际值。我怀疑对于复制任务,这是在复制任务开始之前完成的(在我加载并设置版本号之前)。

我找不到太多关于如何评估 cwd 属性的信息,除了它似乎发生在 grunt 本身的内部。核心 grunt 功能无法正确处理模板似乎很奇怪,但据我所知,它没有发生。

顺便说一句 - 如果我使用指向我的 package.json 文件中的值的模板,所有这些都可以正常工作:

"cwd": "//networkPath/<%= pkg.path.to.version %>/docs"

非常感谢任何帮助

【问题讨论】:

    标签: gruntjs grunt-contrib-copy


    【解决方案1】:

    你可以考虑:

    1. package.json 动态获取版本,同时从您的位置复制项目,使用options.process 函数。
    2. 将其作为属性存储在最初为空的对象中。
    3. 然后稍后在另一个 copy 任务目标中引用它。

    以下要点似乎有效:

    Gruntfile.js

    module.exports = function(grunt) {
    
        grunt.initConfig({
    
            // A 'version' property key and value (obtained via a copied package.json)
            // will be dynamically added to this empty object and referenced later.
            obtainedFromPackage: {},
    
            copy: {
                options: {
                    // Avoid binaries getting corrupted. For more info see:
                    // https://github.com/gruntjs/grunt-contrib-copy/issues/213
                    noProcess: ['**/*.{png,gif,jpg,ico,pdf}']
                },
                initial: {
                    files: [{
                        expand: true,
                        cwd: 'src/',
                        src: '**/*',
                        dest: './copiedItems/'
                    }],
                    options: {
                        // Use/abuse the 'options.process' function to obtain the 'version'
                        // value from the copied 'package.json'. This value is added to a
                        // 'version' property in the empty 'obtainedFromPackage' object.
                        process: function(content, srcpath) {
                            if (srcpath.indexOf('package.json') !== -1) {
                                var pkgVersion = grunt.file.readJSON(srcpath).version;
                                grunt.config('obtainedFromPackage.version', pkgVersion);
                            }
                            return content //Ensure original file content is not deleted.
                        }
                    }
                },
                copyDocs : {
                    files: [{
                        expand: true,
                        // Change directory to version obtained in previous copy task.
                        cwd: './networkPath/<%= obtainedFromPackage.version %>/',
                        src: 'docs/**',
                        dest: './copiedItems/'
                    }]
                }
            }
    
        });
    
        grunt.loadNpmTasks('grunt-contrib-copy');
    
        grunt.registerTask('copyFiles', [
            'copy:initial',
            'copy:copyDocs'
        ]);
    
    };
    

    注意:这显然需要适应您的要求。 特别是路径引用!

    目录设置

    Gruntfile.js 中的示例要点假设一个虚构的项目目录设置如下:

    project
    ├── Gruntfile.js (the one shown above)
    ├── networkPath
    │  ├── 0.0.0
    │  │  └── docs
    │  │      ├── baz
    │  │      │   └── baz.html
    │  │      └── index.html
    │  └── 1.1.1
    │     └── docs
    │         ├── foo
    │         │   └── foo.html
    │         └── index.html
    ├─── node_modules
    │     └── ...
    ├─── package.json
    └─── src
        ├─── a
        │   └─── b.js
        └─── package.json 
    

    ...其中package.jsonversion 属性(位于src 文件夹中)设置为:

    "version": "1.1.1",
    

    ...而名为 networkPath 的文件夹是我假设存储您的文档的位置。

    运行任务

    通过 CLI 执行以下命令:

    $ grunt copyFiles

    结果输出

    运行任务会在根project 目录中创建一个新文件夹,如下所示:

    project
    ├── copiedItems
    │  ├── a
    │  │  └── b.js
    │  ├── docs
    │  │  ├── foo
    │  │  │   └── foo.html
    │  │  └── index.html
    │  └─── package.json
    ├─ ...
    └─ ...
    

    注意事项:

    1. src 文件夹中的所有项目(上面的 目录设置 部分中显示的项目)都被复制到新创建的名为 copiedItems。

    2. docs 文件夹及其内容来自名为 1.1.1 的文件夹(上面的目录设置部分中显示的那个)被复制到新创建的名为 copiedItems 的文件夹中。正在复制此特定文件夹,因为其父目录名称与正在复制的 package.json 的 version 属性匹配。

    我希望这会有所帮助!


    更新:

    在将一些二进制图像添加到src 文件夹后,我发现生成的复制图像已损坏。请参阅此issue 登录grunt-contrib-copy 存储库以获取更多信息。

    上面的Gruntfile.js 现在利用options.noprocess 作为copy 任务中的全局变量作为保护措施。

    现在已成功复制图像文件 :)


    【讨论】:

    • 我复制了您的代码并在本地进行了试用,但得到的结果与我的代码相同。您的代码实际上并没有太大的不同,只是从 package.json 中获取值的方式不同。这从来都不是问题。
    • 我怀疑问题在于我使用的是旧版本的复制库。我看到有几个新版本。我目前无法访问最新的,所以我必须请求它。
    • f.y.i.我使用的版本是grunt-contrib-copy@1.0.0 - 现在很想知道您所说的“得到了与我的代码相同的结果”...您得到的结果是什么?跨度>
    • 第二个复制任务运行但没有任何反应。令人讨厌的是,您看不到它试图从哪个路径复制,但没有复制任何文件,因此某些东西无法正常工作。非常感谢您的帖子,我会在能够获得最新版本时更新。
    • 祝你好运!您可以尝试通过 CLI 使用 --verbose 标志运行任务。例如:$ grunt copyFiles --verbose。这可能有助于揭示什么不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-17
    相关资源
    最近更新 更多