如何配置Webpack使其跟随符号链接以解决copyFiles处理CKEditor文件夹失败问题
解决Webpack copyFiles()不跟随符号链接的问题
问题场景
我在Symfony项目中通过Composer安装了CKEditor,接着执行npm install -D ./vendor/myVendor/ckeditorPackage将其作为本地包安装,这样node_modules/ckeditor4会生成一个指向Composer vendor目录的符号链接,目的是让Webpack始终和Composer保持同步。
之后我在webpack.config.js中配置了copyFiles来复制CKEditor的资源:
.copyFiles([ {from: './node_modules/ckeditor4/', to: 'ckeditor/[path][name].[ext]', pattern: /\.(js|css)$/, includeSubdirectories: false}, {from: './node_modules/ckeditor4/adapters', to: 'ckeditor/adapters/[path][name].[ext]'}, {from: './node_modules/ckeditor4/lang', to: 'ckeditor/lang/[path][name].[ext]'}, {from: './node_modules/ckeditor4/plugins', to: 'ckeditor/plugins/[path][name].[ext]'}, {from: './node_modules/ckeditor4/skins', to: 'ckeditor/skins/[path][name].[ext]'}, {from: './node_modules/ckeditor4/vendor', to: 'ckeditor/vendor/[path][name].[ext]'} ])
但构建时出现警告:
WARNING The "from" option of copyFiles() should be set to an existing directory but "./node_modules/ckeditor4/" seems to be a file. Nothing will be copied for this copyFiles() config object.
排查后发现./node_modules/ckeditor4/是符号链接,执行ls -l | grep cked的结果验证了这一点:
lrwxrwxrwx 1 user user 63 de jul. 29 13:00 ckeditor4 -> ../vendor/myVendor/ckeditorPackage
解决方案
问题的核心是Webpack Encore的copyFiles方法底层依赖的copy-webpack-plugin默认不跟随符号链接,它会把符号链接当成普通文件处理,导致无法识别实际的目录结构。我们只需要在copyFiles的配置中显式开启followSymlinks: true选项即可。
你有两种配置方式:
- 为每个复制项单独设置:在每个
copyFiles的配置对象中添加followSymlinks: true
.copyFiles([ {from: './node_modules/ckeditor4/', to: 'ckeditor/[path][name].[ext]', pattern: /\.(js|css)$/, includeSubdirectories: false, followSymlinks: true}, {from: './node_modules/ckeditor4/adapters', to: 'ckeditor/adapters/[path][name].[ext]', followSymlinks: true}, {from: './node_modules/ckeditor4/lang', to: 'ckeditor/lang/[path][name].[ext]', followSymlinks: true}, {from: './node_modules/ckeditor4/plugins', to: 'ckeditor/plugins/[path][name].[ext]', followSymlinks: true}, {from: './node_modules/ckeditor4/skins', to: 'ckeditor/skins/[path][name].[ext]', followSymlinks: true}, {from: './node_modules/ckeditor4/vendor', to: 'ckeditor/vendor/[path][name].[ext]', followSymlinks: true} ])
- 全局设置(更简洁):在
copyFiles的第二个参数中设置全局选项,所有复制项都会继承这个配置:
.copyFiles([ {from: './node_modules/ckeditor4/', to: 'ckeditor/[path][name].[ext]', pattern: /\.(js|css)$/, includeSubdirectories: false}, {from: './node_modules/ckeditor4/adapters', to: 'ckeditor/adapters/[path][name].[ext]'}, {from: './node_modules/ckeditor4/lang', to: 'ckeditor/lang/[path][name].[ext]'}, {from: './node_modules/ckeditor4/plugins', to: 'ckeditor/plugins/[path][name].[ext]'}, {from: './node_modules/ckeditor4/skins', to: 'ckeditor/skins/[path][name].[ext]'}, {from: './node_modules/ckeditor4/vendor', to: 'ckeditor/vendor/[path][name].[ext]'} ], { followSymlinks: true })
原理说明
开启followSymlinks后,copy-webpack-plugin会解析符号链接指向的实际目录,而不是把它当作一个文件,这样就能正常识别并复制CKEditor的所有资源文件了,同时也能保持你原本想要的Webpack与Composer同步的需求。
内容的提问来源于stack exchange,提问作者enboig
相关产品推荐
相关产品推荐

