(转)cube-ui后编译
转载地址:https://www.jianshu.com/p/189755f9ce43
1. 后编译介绍
目前大部分的前端项目开发都是使用es6+的代码并且使用babel进行编译,而传统的对代码包的引入都是引入一个被babel编译好的文件入口,这样带来了一个缺点,那就是项目中无用的代码也会被引入到最终打包的文件中。
后编译的思想是不会在包发布的时候进行编译,而是会在使用这个包的前端项目构建的时候进行编译。
下面就来看一下cube-ui对更好的使用后编译作出的探索。
2. 后编译遇到的问题
2.1 后编译和普通编译的兼容
由于webpack的开发团队也考虑到直接引入一个编译好的代码包带来的一些问题,所以在webpack2.x之后引入了一个属性。
module.exports = {
// ...
resolve: {
mainFields: ["browser", "module", "main"]
}
// ...
}
在引入一个第三方包的时候,会根据mainFields的队列头到队列尾的顺序检测package.json文件中是否有这些字段值。
上面的示例代码是target值为webworker时的默认配置,当target为其他值时,mainFields的默认值为:
mainFields: ["module", "main"]
在使用cube-ui时我们如何配置使用后编译或者时普通编译呢?
后编译时直接引入代码包时就会默认引入ES2015 module的代码,对于普通编译需要在webpack.base.conf.js中配置别名解析。
module.exports = {
// ...
resolve: {
alias: {
// ...
"cube-ui": "cube-ui/lib"
}
}
// ...
}
这样在引入时就可以引入到编译后的代码。
2.2 引入路径
在做到上面的几步后,就可以实现代码包的后编译,但是这里有一个引入路径的问题。比如我们要引入cube-ui的switch组件,我们需要这样引入:
import Switch from 'cube-ui/src/modules/switch'
这样的引入方式对于用户来说肯定不是很友好。
通过cube-ui团队开发的webpack插件webpack-transform-modules-plugin可以通过下面的方式进行组件的引入。
import {Switch} from 'cube-ui'
在引入这个插件的同时需要在package.json中引入下面的代码:
{
// ...
"transformModules": {
"cube-ui": {
"transform": "cube-ui/src/modules/${member}",
"kebabCase": true
}
},
// ...
}
通过这段配置来解析cube-ui的引入路径。
同时还要在webpack.base.conf.js中添加webpack-transform-modules-plugin插件。
var PostCompilePlugin = require('webpack-post-compile-plugin')
var TransformModulesPlugin = require('webpack-transform-modules-plugin')
module.exports = {
// ...
plugins: [
// ...
new PostCompilePlugin(),
new TransformModulesPlugin()
]
// ...
}
2.3 嵌套后编译
如果我们要使用后编译还要在webpack配置的rules中加入include配置,比如要后编译代码包A和B,就要写下面的代码:
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /\.js$/,
loader: 'babel-loader',
// 注意这里的 include
// 除了 src 还包含了额外的 node_modules 下的两个包
include: [
resolve('src'),
resolve('node_modules/A'),
resolve('node_modules/B')
]
},
// ...
]
},
// ...
}
如果在后编译的生态中,会出现下面的情况:
这里借用cube-ui团队的一张嵌套后编译的图。
当A为后编译,A依赖的包C和D也为后编译时,需要在应用的webpack配置中增加rules.include的配置:
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /\.js$/,
loader: 'babel-loader',
// 注意这里的 include
// 除了 src 还包含了额外的 node_modules 下的两个包
include: [
resolve('src'),
resolve('node_modules/A'),
resolve('node_modules/B'),
resolve('node_modules/C'),
resolve('node_modules/D')
]
},
// ...
]
},
// ...
}
cube-ui团队为了解决这种情况开发了webpack插件webpack-post-compile-plugin,通过这个插件可以通过获取package.json文件中的compileDependencies属性来获取当前包依赖的后编译包,并且将这些包添加到webpack配置的rules.include中。
webpack-post-compile-plugin插件的核心代码如下:
PostCompilePlugin.prototype.apply = function (compiler) {
var that = this
compiler.plugin(['before-run', 'watch-run'], function (compiler, callback) {
// ...
var dependencies = that._collectCompileDependencies(compiler)
if (dependencies.length) {
var rules = compiler.options.module.rules
rules && rules.forEach(function (rule) {
if (rule.include) {
if (!Array.isArray(rule.include)) {
rule.include = [rule.include]
}
rule.include = rule.include.concat(dependencies)
}
})
}
callback()
})
}
就是在webpack编译过程中的before-run和watch-run的两个钩子中进行依赖的收集。
3. 使用后编译的其他问题
由于cube-ui使用的是stylus进行样式的编写,如果采用后编译需要在前端工程中配置stylus的解析。
在vue-loader的配置中添加下面的配置。
const stylusOptions = {
'resolve url': true
} return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus',stylusOptions),
styl: generateLoaders('stylus',stylusOptions)
}
总结
后编译的优点是能对依赖包中的代码进行依赖分析,从而让公共的依赖被提取出来。由于后编译是在前端应用构建时一起构建,所以babel转换的API只有一份,不会冗余。
缺点是包的babel配置要与应用的babel配置兼容,依赖包不能使用alias和DefinePlugin。编译时间会变长。
后编译是一种生态,如果你编写的代码包需要使用后编译,那么就要遵守后编译的配置规定。
作者:imamba
链接:https://www.jianshu.com/p/189755f9ce43
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
(转)cube-ui后编译的更多相关文章
- C++ 升级到 Vs2013后编译设置
编译 EasyDarwin 时,Vs2008的C++升级到 Vs2013时报错: 1. 找不到 windows.h 项目->属性->配置属性->C/C++->所有选项: 附加包 ...
- Cocos2d-x3.0 载入Cocostudio的UI后,button无法点击的解决方法
原帖地址:http://blog.csdn.net/musicvs/article/details/28390617 近期发现不少朋友都遇到这个问题,用Cocostudio的UI编辑器创建好UI后,在 ...
- QT添加自定义信号后编译出现undefined reference
QT添加自定义信号后编译出现undefined reference 这是需要重新生成qmake: build --->run qmake
- weblogic自带的jdk是在工程的包部署后编译使用
weblogic自带的jdk是在工程的包部署后编译使用的.当用户把项目打包部署到weblogic上面,运行该项目的java环境jdk就是用的weblogic自带的jdk了,工程中的jdk和编译时的jd ...
- carsim2016 与 MATLAB2018 联合仿真send to simulink后编译不成功解决方法
之前使用CarSim8.1和Matlab17b联合仿真时遇到的问题和现在换用Carsim2017之后遇到了不一样的问题.carsim2017界面选择send to simulink 按钮之后,点击运行 ...
- VS项目中使用Nuget还原包后编译生产还一直报错?
Nuget官网下载Nuget项目包的命令地址:https://www.nuget.org/packages 今天就遇到一个比较奇葩的问题,折腾了很久终于搞定了: 问题是这样的:我的解决方案原本是好好的 ...
- pro*c添加SQLCHECK后编译报错PLS-S-00201
如果在pro*c中调用数据库了里的函数,就需要在proc的cfg配置文件中添加一行: SQLCHECK=SEMANTICS 但是添加之后又会出现PLS-S-00201错误,原因在与添加SQLCHECK ...
- apache安装后编译新模块
1.下载对应版本的源码包 2.解压后找到modules/mappers目录并进入 3.运行如下命令自动编译.安装和修改httpd.conf文件: /usr/sbin/apxs -c -i -a mod ...
- Android问题-DelphiXE8安装后编译Android提示SDK无法更新问题(XE10也可以解决)
资料来原:http://www.chenruixuan.com/archives/479.html (DelphiXE8 更新SDK)http://www.dfwlt.com/forum.php?mo ...
随机推荐
- いくnotepad++
再见!Notepad++,好走不送! 1No zuo No Die 上周就发现Notepad++开发者在作妖,新版本放了个啥恶心的标注上来,本来想直接发文说一说,后来想想是不是这样又给它做了宣传,就决 ...
- 【转】C++ - 结构体构造函数使用总结
声明 转载自:https://www.cnblogs.com/wlw-x/p/11566191.html 关于结构体构造函数使用总结 三种结构体初始化方法 1.利用结构体自带的默认构造函数 2.利用带 ...
- leetcode 双周赛9 找出所有行中最小公共元素
给你一个矩阵 mat,其中每一行的元素都已经按 递增 顺序排好了.请你帮忙找出在所有这些行中 最小的公共元素. 如果矩阵中没有这样的公共元素,就请返回 -1. 示例: 输入:mat = [[,,,,] ...
- Vue 监听鼠标左键 鼠标右键以及鼠标中键修饰符click.left&contextmenu&click.middle
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- TensorFlow中实现RNN,彻底弄懂time_step
这篇博客不是一篇讲解原理的博客,这篇博客主要讲解tnesorlfow的RNN代码结构,通过代码来学习RNN,以及讲解time_steps,如果这篇博客没有让你明白time_steps,欢迎博客下面评论 ...
- Java连载49-常量格式、package包介绍
一.常量 1.常量的定义:final修饰的实例变量是不可变的,这种变量一般和static联合使用,被称为“常量” 2.常量的语法格式: public static final 类型 常量名 = 值: ...
- python写文件时,使用代码强制刷新文件
一.实验环境 1.Windows10x64 2.anaconda4.6.9 + python3.7.1(anaconda集成,不需单独安装) 3.pyinstaller3.5 二.任务需求 三.问题描 ...
- LeetCode 217:存在重复元素 Contains Duplicate
题目: 给定一个整数数组,判断是否存在重复元素. Given an array of integers, find if the array contains any duplicates. 如果任何 ...
- 借助Git实现本地与GitHub远程双向传输(同步GitHub仓库)以及一些使用错误解决
前言 GitHub作为程序员必备的学习交流平台,虽然在国内速度不算快,但只要好好利用这个平台,我相信还是可以学习到很多东西.在暑期的时候,我曾经就初次远程连接到了GitHub,但开学后,不知道为什么又 ...
- 手写SpringMVC实现过程
1. Spring Boot,Spring MVC的底层实现都是Servlet的调用. 2. Servlet的生命周期里面首先是类的初始化,然后是类的方法的调用,再次是类的销毁. 3. 创建一个spr ...