rollup比較適合打包js的sdk或者封裝的框架等,例如,vue源碼就是rollup打包的。webpack比較適合打包一些應用,例如SPA或者同構項目等等。最近咱們對rollup小試牛刀了一下。簡單分享一些注意事項吧。css
rollup基礎知識及插件的一些使用,網上有很多資料,能夠去查閱。vue
rollup中文網:www.rollupjs.com/guide/zh#-d…node
下面主要記錄一下rollup使用過程當中的一些報錯及解決方案吧。webpack
You must supply options.name for IIFE bundleses6
出現這個報錯,是要在options中指定name,例如以下:web
output: {
file: resolve(`js/haorooms.${type}.js`),
format: type,
name: 'haorooms',
banner
},
複製代碼
[!] (commonjs plugin) SyntaxError: Unexpected tokennpm
出現這個問題,可能有幾個緣由json
一、rollup-plugin-commonjs未引入,或者加載循序不對瀏覽器
咱們知道,webpack loader是有加載循序的(從右到左,從下到上),rollup雖然沒有嚴格的加載循序,可是我一般是將commonjs放到babel編譯以後。以下:babel
babel({
exclude: 'node_modules/**', // 排除node_modules 下的文件
runtimeHelpers: true
}),
commonjs(),
複製代碼
二、缺乏babel類 我按照babel類熟悉編譯插件做爲這個項目的依賴。
npm install --save-dev babel-plugin-transform-class-properties
複製代碼
.babelrc配置以下:
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-runtime", "external-helpers","transform-class-properties"]
}
複製代碼
注:上面的配置是babel 7.0如下的方式,假如babel7.0以上,用另外的方式配置,參見:babeljs.io/docs/en/v7-…
code: 'BAD_BUNDLE_TRANSFORMER', plugin: 'uglify'
這個問題比較坑爹,其實我用rollup打包demo代碼是沒有問題的,可是打包個人js就有問題了,好奇怪,後來我發現是swiper的問題,由於我依賴了swiper。關於swiper打包,在webpack中也有問題,一般babel打包以後,並不會把swiper的es6語法轉換。有時候webapck也會報錯,大體是
dom7 undefined ..
複製代碼
webpack解決方案以下:
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'swiper': 'swiper/dist/js/swiper.js',
'@': resolve('src')
}
},
複製代碼
指定一個別名
可是發現rollup中好像沒有這個方式,無奈,我在引入swiper的時候以下處理
import Swiper from 'swiper/dist/js/swiper.js'
複製代碼
這樣打包的時候就不會有問題了。
process not defined
複製代碼
這個錯誤是在打包成功以後,瀏覽器運行發現的,發現打包以後的代碼中有process.env.NODE_ENV
解決方案:
import replace from 'rollup-plugin-replace'
const env = process.env.NODE_ENV
plugins: [
replace({
'process.env.NODE_ENV': JSON.stringify(env)
}),
]
複製代碼
把 process.env.NODE_ENV這個替換掉
咱們用rollup打包,通常都會打以下方式
amd – 異步模塊定義,用於像RequireJS這樣的模塊加載器
cjs – CommonJS,適用於 Node 和 Browserify/Webpack
es – 將軟件包保存爲ES模塊文件
iife – 一個自動執行的功能,適合做爲<script>標籤。(若是要爲應用程序建立一個捆綁包,您可能想要使用它,由於它會使文件大小變小。)
umd – 通用模塊定義,以amd,cjs 和 iife 爲一體
複製代碼
我是用node,循環讀取的方式,配置以下:
const babel = require('rollup-plugin-babel')
const node = require('rollup-plugin-node-resolve')
const commonjs = require('rollup-plugin-commonjs')
const json = require('rollup-plugin-json')
const replace = require('rollup-plugin-replace')
const uglify = require('rollup-plugin-uglify')
// 新增 rollup-plugin-postcss 插件
const postcss = require('rollup-plugin-postcss')
// 新增 postcss plugins
const simplevars = require('postcss-simple-vars')
const nested = require('postcss-nested')
const cssnext = require('postcss-cssnext')
const cssnano = require('cssnano')
const version = process.env.VERSION || require('../package.json').version
const path = require('path')
const fs = require('fs')
const ora = require('ora')
const terser = require('terser')
const zlib = require('zlib')
const spinner = ora('building for production...')
spinner.start()
const rollup = require('rollup')
if (!fs.existsSync('dist')) {
fs.mkdirSync('dist')
}
function resolve(dir) {
return path.join(__dirname, '..', dir)
}
const banner =
'/*!\n' +
` * haoroomsjssdk v${version}\n` +
` * (c) 2017-${new Date().getFullYear()}\n` +
' * Released under the MIT License.\n' +
' */'
// amd – 異步模塊定義,用於像RequireJS這樣的模塊加載器
// cjs – CommonJS,適用於 Node 和 Browserify/Webpack
// es – 將軟件包保存爲ES模塊文件
// iife – 一個自動執行的功能,適合做爲<script>標籤。(若是要爲應用程序建立一個捆綁包,您可能想要使用它,由於它會使文件大小變小。)
// umd – 通用模塊定義,以amd,cjs 和 iife 爲一體
const buildArray = ['amd', 'cjs', 'iife', 'umd']
let allConfig = []
const env = process.env.NODE_ENV
let baseConfig = {
plugins: [
postcss({
extensions: ['.css'],
plugins: [
simplevars(),
nested(),
cssnext({ warnForDuplicates: false }),
cssnano()
]
}),
node({
jsnext: true, // 該屬性是指定將Node包轉換爲ES2015模塊
// main 和 browser 屬性將使插件決定將那些文件應用到bundle中
main: true, // Default: true
browser: true // Default: false
}),
json(),
babel({
exclude: 'node_modules/**', // 排除node_modules 下的文件
runtimeHelpers: true
}),
commonjs(),
replace({
'process.env.NODE_ENV': JSON.stringify(env)
}),
(env === 'production' && uglify())
]
}
buildArray.forEach(item => {
let outputs = {
input: resolve('src/haorooms.js'),
output: {
file: resolve(`js/haorooms.${item}.min.js`),
format: item,
name: 'haorooms',
banner
}
}
allConfig.push(Object.assign({}, baseConfig, outputs))
})
function build (builds) {
let built = 0
const total = builds.length
const next = () => {
buildEntry(builds[built]).then(() => {
built++
if (built < total) {
next()
} else {
spinner.stop()
}
}).catch(logError)
}
next()
}
function buildEntry (config) {
const output = config.output
const { file, banner } = output
const isProd = /min\.js$/.test(file)
return rollup.rollup(config)
.then(bundle => bundle.generate(output))
.then(({ code }) => {
if (isProd) {
const minified = (banner ? banner + '\n' : '') + terser.minify(code, {
output: {
ascii_only: true
},
compress: {
pure_funcs: ['makeMap']
}
}).code
return write(file, minified, true)
} else {
return write(file, code)
}
})
}
function write (dest, code, zip) {
return new Promise((resolve, reject) => {
function report (extra) {
console.log(blue(path.relative(process.cwd(), dest)) + ' ' + getSize(code) + (extra || ''))
resolve()
}
fs.writeFile(dest, code, err => {
if (err) return reject(err)
if (zip) {
zlib.gzip(code, (err, zipped) => {
if (err) return reject(err)
report(' (gzipped: ' + getSize(zipped) + ')')
})
} else {
report()
}
})
})
}
function getSize (code) {
return (code.length / 1024).toFixed(2) + 'kb'
}
function logError (e) {
console.log(e)
}
function blue (str) {
return '\x1b[1m\x1b[34m' + str + '\x1b[39m\x1b[22m'
}
build(allConfig)
複製代碼
運行的時候直接以下:
cross-env NODE_ENV=production node 上面的文件名
複製代碼
備註:cross-env 能夠指定環境變量等
另一種方式是用npm run all
參見地址:www.npmjs.com/package/npm…
能夠用這個來運行多個npm 命令,來達到運行一次,打包全部的功能!
本文來源haorooms博客:www.haorooms.com/post/rollup…