更优雅的使用 Parcel 进行前端项目的打包
Parcel 有着开箱即用的特性, 为我们初始化工程省却了许多时间, 但是零配置的特性导致我们比较不方便进行一些预处理, 这篇文章就带领读者解决一些我们常会遇到的一些问题. 只需要很简单的添加几个参数,就可以满足我们大部分的特殊情况.
在去年, Parcel 没有支持 SourceMap 的特性, 导致于无法进行断点调试, 从而很多团队没有在生产中使用 Parcel, 现在 Parcel 已经支持 SourceMap 的特性, 再加上可以很方便的编写插件去填补一些自定义的功能, 所以 Parcel 我认为已经可以在新项目的生产中投入使用了.
本文作者简单的编写了一个 parcel-plugin-change-file
插件示例, 来满足下面的功能, 具体使用请继续阅读文章内容.
本文不会对 Parcel 的基础使用再多做解释, 如果您还没有接触过 Parcel ,请先去了解: Parcel 官方文档-快速开始
如何跳过不需要打包的文件?
如果我们使用 parcel index.html
命令, Parcel 会自动识别html中的引用,如果是http://
就不会进行打包处理, 如果是本地文件,就会识别成Assets对象,进行打包.
如果我们需要跳过对本地文件的打包, 我们可以使用 parcel-plugin-change-file
插件
$ yarn add -D parcel-plugin-change-file
在 index.html中添加 `` , 注意这里有两个中括号.
<body>
<!--[ <script src="lodash.min.js"></script> ]-->
</bodt>
当项目编译结束之后, 该插件会把 `` 的注释内容打开,从而跳过 Parcel 的打包检测.
<body>
<script src="lodash.min.js"></script>
</bodt>
如何对html进行修改?
例如, 我们尝试根据 package.json
中的信息修改 index.html
的 title
在项目跟路径创建 parcel-plugin-change-file.js 文件
const package = require('./package.json')
module.exports = {
html: [package.name],
};
在 src/index.html
中添加 `` , 其中 i
对应之前 html
对象中的数组下标, 这里我们只有一个, 所以用 0
<header>
<title><!-- parcel-plugin-change-file-0 --></title>
</header>
当项目编译结束之后, 该插件会把 package.json
中的 name
信息插入到 title
<body>
<title>Parcel优雅配置</title>
</bodt>
如何在parcel打包结束之后拷贝一些文件到打包目录?
例如, 某些情况, 我们不需要 Parcel 帮我们处理 png
图片, 我们希望直接使用图片路径:
class Banner extends React.Componet {
render(){
return <div style={{
backgoundImage:'img/test.png'
}} ></div>
}
}
那我们就需要在打包之后再把图片拷贝到相应的路径.
还是确保parcel-plugin-change-file
已被安装, 然后在项目跟路径创建parcel-plugin-change-file.js
module.exports = {
copy: ['src/assets', 'src/documents'],
};
正常执行 Parcel 打包脚本, 就会把 src/assets
和 src/documents
的子内容拷贝到打包输出的跟路径
$ parcel src/index.html
如何达到和 webpack.DllPlugin
一样的预先编译的效果呢?
Webpack 的 DllPlugin 插件可以把一些不常进行修改的库提前编译成一个文件, 然后在项目里引用, 经过配置webpack不会再次编译这些已经编译过的文件.这样可以大大的加速平时编译的时间. 从而赶上 Parcel 的打包速度.
而在 Parcel 中,也可以可以把一些不常进行修改的库提前编译成一个文件, 这样可以在 Parcel 原本就快速的编译前提下再减去绝大部分的编译内容, 从而极大的加速平时编译的时间, 不过就只能使用全局对象引用了.
在Parcel项目中, 是可以使用全局对象的, 例如我们在html中引入一个lodash:
<body>
<script src="https://cdn.bootcss.com/lodash.js/4.17.9/lodash.min.js"></script>
</body>
此时, 在项目中不需要import _ from 'lodash'
, 可以识别全局_
对象的
console.log(_.map) //可以打印出 _.map 方法
有了以上知识点,我们可以这样做:
- 创建一个预先需要打包的文件:
// dll/default.js
// 假设这些库是自己编写的库, 需要在预编译, 并且在全局引用
import _ from 'lodash';
import Immutable from 'immutable';
// 暴露到全局对象中
window['_'] = _;
window['Immutable'] = Immutable;
- 使用Parcel进行打包, 其中
changeFile=false
是不使用 parcel-plugin-change-file 插件:
$ changeFile=false parcel build dll/default.js -d src/dll -o defalut.min.js
以上 default.min.js
已经创建好了, 接下来是在平时 Parcel 的项目中使用它
- 我们需要在
src/index.html
里引入src/dll/default.min.js
<head>
<!--[ <script src="default.min.js"></script> ]-->
</head>
- 创建parcel-plugin-change-file.js
module.exports = {
copy: ['src/dll'],
};
- 大功告成,可以在项目里直接使用之前
default.min.js
中暴露在window
下的全局对象
// src/index.js
_.map(_.range(500), v=>{
console.log(`hello:${v}`);
})
- 如果需要有提示, 需要编写 .d.ts 文件, 然后在项目中引入
这一块知识点请查阅 typescript Declaration Files 文档
/// <reference path="./your-edit.d.ts"/>
启动项目:
$ parcel src/index.html