2018年1月到4月,我使用 Parcel 和 React 完成了CMS功能。
回顾这段时间,我遇到了很多挑战。
在这里分享一下。
Points:
- Parcel 特性、优缺点。
- Parcel 常用命令和配置。
- 使用 Parcel 完成实际项目,并解决实际问题。
1. Parcel 特性、优缺点
关于 Parcel 特性、优缺点,Parcel 官方已经有很多介绍了。我写几条我比较在乎的。
优点
- 开箱即用的转换器和内置的编译器。
Babel 转换 JavaScript,PostCSS 转换 CSS,使用 CSS Modules 超级简单。 - 零配置代码拆分,开箱即用。
缺点
- 并不是零配置,实际项目中还是需要配置很多内容。
但是要比 Webpack 简单。 - 仅支持单一入口。
- 不支持 proxy。
官方觉得,这不是打包工具应该做的事。但是我觉得 Parcel 已经不仅仅是一个打包工具了,应为它也自带服务器。
Issue - 不支持 HTML模版
- 只针对 Web 应用,对库并不友好。
- 起步晚,最佳实践少,手脚架少。
综上所述,个人觉得开发 Web 应用,Parcel 还是值得推荐的。开发库,请慎重。
选择 Parcel 遇到的挑战肯定比选择 Webpack 遇到的挑战要多,要有不怕折腾的心态。
2. Parcel 常用命令和配置
仅介绍我是如何使用 Parcel 的。
1. 开发模式
使用 cross-env 设置环境变量,--open
自动打开浏览器
"start": "cross-env NODE_ENV=development parcel src/index.html --open",
2. 生产模式
--no-cache
和 --public-url
指定服务URL
"build": "cross-env NODE_ENV=production parcel build src/index.html -d build --no-cache --public-url /cms/",
3. PostCSS 配置
使用 CSS Modules、autoprefixer,并指定插件有效的浏览器版本。
// .postcssrc
{
"modules": true,
"plugins": {
"autoprefixer": {
"grid": true
}
}
}
// package.json
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 10"
]
3. 使用 Parcel 完成实际项目,并解决实际问题。
这个真的能写好多。
1. 使用 Parcel 作为打包工具,定制 Antd 样式变得相对困难。
官方推荐的 theme 属性,不能使用。
解决方案:只能使用 less 文件进行变量覆盖。
@import "~antd/dist/antd.less"; // 引入官方提供的 less 样式入口文件
@import "your-theme-file.less"; // 用于覆盖上面定义的变量
这种方式会直接载入 Antd 所有的样式,性能不算最优解。
2. PostCSS-Modules 的 globalModulePaths 不起作用
Issue
官方未解决。
解决方案:不使用这个配置。
3. Uncaught TypeError: moment.locale is not a function
这个问题是在做国际化是发生的,Issue。
官方已解决,Issue。
4. AntD iconfont 本地部署失败
初始方案:
@import "./node_modules/antd/dist/antd.less"; // 引入官方提供的 less 样式入口文件
@icon-url: "./iconfont/iconfont"; // 把 iconfont 地址改到本地
因为我们使用 CSS Modules ,并且由于Parcel 中 PostCSS-Modules 的 globalModulePaths 不起作用,antd.less 会被转化成 css modules。
解决方案:使用 iconfont-plus 代替 AntD 的 Icon 组件。
5. vim 下HMR(热模块重载)不工作。
项目组并没有强制统一编辑器,所以有同事使用 vim 开发。心疼他们。
HMR 不工作原因是 vim 的安全写入机制。
解决方案:将 :set backupcopy=yes
添加到 vim 设置。
6. html 无法通过相对路径引入其他项目的 js 文件。
需求:引入公司定制的 ckeditor 4。
初始做法:
<script src="/other/js/ckeditor.js"></script>
期待结果,引入当前环境的 /other/js/ckeditor.js
文件。
但是,Parcel 在打包时直接出错,原因是没有找到文件。
解决方案:使用 js 在运行时插入 <script src="/other/js/ckeditor.js"></script>
。
伪代码如下:
// 第一步:获取当前环境的 domain。(主要针对本地开发)
const domain = process.env.domain == null ? '' : process.env.domain
// 第二步:插入 <script />
export function loadCKEditor4() {
const script1 = document.createElement('script')
script1.src = `${domain}/js/common/all-nodebug-comp.js`
const script2 = document.createElement('script')
script2.src = `${domain}/js/common/popup.js`
const scriptCKEditor4 = document.createElement('script')
scriptCKEditor4.src = `${domain}/dui/ckeditor/ckeditor.js`
document.body.appendChild(script1)
document.body.appendChild(script2)
document.body.appendChild(scriptCKEditor4)
}
// 第三步:React 渲染
ReactDOM.render(<VeryCool />, document.getElementById('cms-container'))
核心:在 React 渲染之前插入 <script />
。
最后,如果大家也有在实际项目中使用 Parcel 经验,希望能和大家交流经验。
首发:https://iamtjcn.github.io/2018/05/23/parceljs/