基於rollup打包組件實戰

前言

最近做項目,發現有很多可抽離出來的組件,以前開發組件是用gulp和webpack搭建的腳手架,需要配置一堆loader之類的東西,配置完成後,編譯出來的代碼不僅可讀性差,而且代碼體積偏大。因此想找尋新的編譯工具,最後發現vue.jsreact.js等流行庫都用了rollup.js來編譯代碼,而且rollup.js可以編譯輸出各種模塊規範的代碼AMD、Commonjs、UMD、IIFE。所以也入門rollup.js

rollup介紹

官方描述

Rollup 是一個 JavaScript 模塊打包器,可以將小塊代碼編譯成大塊複雜的代碼,例如 library 或應用程序。Rollup 對代碼模塊使用新的標準化格式,這些標準都包含在 JavaScript 的 ES6 版本中,而不是以前的特殊解決方案,如 CommonJS 和 AMD。ES6 模塊可以使你自由、無縫地使用你最喜愛的 library 中那些最有用獨立函數,而你的項目不必攜帶其他未使用的代碼。ES6 模塊最終還是要由瀏覽器原生實現,但當前 Rollup 可以使你提前體驗。rollupjs官網

1、配置文件

1、安裝對應的包


// rollup編譯的核心模塊
npm install rollup -D   

// rollup的ES6編譯插件
npm install rollup-plugin-babel -D

// 一堆編譯的loader
npm install -D @babel/cli @babel/core @babel/node @babel/plugin-transform-react-jsx @babel/preset-env @babel/preset-react @babel/runtime @babel/plugin-external-helpers @babel/plugin-proposal-object-rest-spread @babel/plugin-syntax-object-rest-spread 

// plugin插件
npm install -D rollup-plugin-commonjs rollup-plugin-node-resolve rollup-plugin-serve rollup-plugin-uglify rollup-plugin-livereload rollup-plugin-postcss

2、文件目錄


.
├── build // 編譯打包後的文件夾
│   ├── css
│   │   └── index.css // css
│   ├── img  // 圖片無法自動打包過去
│   │   ├── plusRightsTab.png
│   │   └── qiy-icon_1.png
│   └── js
│       └── index.js
├── config
│   ├── build.js
│   ├── compile_task.js      // 編譯文件
│   ├── dev.js
│   ├── rollup.config.dev.js     // 開發環境配置文件
│   ├── rollup.config.js     // 公用配置文件
│   └── rollup.config.prod.js       // 生產環境配置文件
├── index.html          入口html
├── package-lock.json
├── package.json
├── postcss.config.js        // 移動端將px轉換爲rem的配置文件
└── src
    ├── img
    │   ├── plusRightsTab.png
    │   └── qiy-icon_1.png
    ├── js
    │   └── index.js
    └── sass
        ├── _init.scss
        ├── _mixin.scss
        └── tabs.scss
    

2、rollup配置

1、編譯配置文件rollup.config.js

/**
 * Created by wangjia16 on 2019/8/12.
 */
const ENV = process.env.NODE_ENV;
const path = require('path');
const babel = require('rollup-plugin-babel');
const buble = require('rollup-plugin-buble');
const json = require('rollup-plugin-json');

// 編譯npm模塊及其全局變量模塊 插件模塊
const nodeResolve = require('rollup-plugin-node-resolve');
const commonjs = require('rollup-plugin-commonjs');
const nodeGlobals = require('rollup-plugin-node-globals');
//開啓服務插件
const serve = require('rollup-plugin-serve');
//編譯css
const postcss = require('rollup-plugin-postcss');
const sass = require('node-sass');
// 處理rem換算
// const pxtorem = require('postcss-pxtorem');
const px2rem = require('postcss-px2rem');

const image = require('rollup-plugin-img');
// 監聽文件改變,並刷新瀏覽器
const livereload = require('rollup-plugin-livereload');

const resolveFile = function (filePath) {
    return path.join(__dirname, '..', filePath)
};

const resoleFileName = function (filePath) {
    let imgPath = '../build';
    return path.join(__dirname, imgPath, filePath)
};

const isProductionEnv = ENV === 'production';

const processSass = function(context, payload) {
    return new Promise(( resolve, reject ) => {
        sass.render({
            file: context
        }, function(err, result) {
            console.log(result);
            if( !err ) {
                resolve(result);
            } else {
                console.log(err);
                reject(err)
            }
        });
    })
};


module.exports = [
    {
        input: resolveFile('src/js/index.js'),
        output: {
            file: resolveFile(`build/js/index.js`),
            // format: 'cjs',
            format: 'umd',
            name: 'panTabs',
        },
        plugins: [
            postcss({
                extract: './build/css/index.css',
                // extract: true,
                minimize: isProductionEnv,
                extensions:['css','scss'],
                process:processSass,

            }),
            json(),
            babel({
                exclude: '**/node_modules/**'
            }),
            buble(),
            nodeResolve({
                // module: true, // ES6模塊儘可能使用 ‘module’字段
            }),
            commonjs({
                include: [
                    'node_modules/**'
                ],
                exclude: [
                    'node_modules/process-es6/**'
                ],
                namedExports: {
                    'node_modules/react/index.js': ['Component', 'PureComponent', 'Fragment', 'Children', 'createElement']
                }
            }),
            nodeGlobals(),
            // 開啓服務
            ENV == 'development' ?
            serve({
                open: true, // 是否打開瀏覽器
                contentBase: './', // 入口html的文件位置
                historyApiFallback: true, // Set to true to return index.html instead of 404
                host: 'localhost',
                port: 3003
            })
            : '',
            livereload()
        ],
    },
];

注意:如果是umd,需要注意的是umd格式必須指定模塊的名稱,通過name屬性來實現

在這裏插入圖片描述

2、編譯rollup.config.dev.js文件

process.env.NODE_ENV = 'development';
const configList = require('./rollup.config');

configList.map((config, index) => {
    config.output.sourcemap = true;
    return config;
});


module.exports = configList;

3、編譯rollup.config.prod.js文件

process.env.NODE_ENV = 'production';
const { uglify } = require('rollup-plugin-uglify');
const configList = require('./rollup.config');

configList.map((config, index) => {
    config.output.sourcemap = false;
    config.plugins = [
        ...config.plugins,
        ...[
            uglify()
        ]
    ];
    return config;
});

module.exports = configList;

4、.babelrc文件配置

{
  "presets": [
    "@babel/preset-react",
    [
      "@babel/preset-env",
      {
        "modules": false
      }
    ]
  ],
  "plugins": [
    "@babel/plugin-proposal-object-rest-spread",
    "@babel/plugin-syntax-object-rest-spread",
    "@babel/plugin-transform-react-jsx",
    [
      "@babel/plugin-transform-runtime",
      {
        "absoluteRuntime": false,
        "corejs": false,
        "helpers": false,
        "regenerator": false,
        "useESModules": false
      }
    ]
  ]
}

5、在package.json裏配置執行腳本


"dev": "node ./config/dev.js",
 "build": "node ./config/build.js"

執行腳本,編譯

1、執行腳本後,會自動啓動瀏覽器

  • 在項目中執行npm run dev,編譯結果在目錄build/index.js
  • 編譯結果爲
    在這裏插入圖片描述

常見錯誤

1、編譯react時,plugins位置放置不對,會導致語法錯誤

 plugins: [
	 // 原先的位置,放在這裏會導致語法錯誤
	 // nodeResolve(),
     // commonjs(),
     // nodeGlobals(),
     postcss({
        extract: true,
        minimize: isProductionEnv,
        extensions:['css','scss'],
        process:processSass        
      }),
      json(),
      babel({
          exclude: '**/node_modules/**'
      }),
       buble(),
       nodeResolve(),
       commonjs(),
       nodeGlobals(),       
]

在這裏插入圖片描述
2、編譯react,還會出現的錯誤
在這裏插入圖片描述

意思是說 React目前沒有真正提供ES模塊,所以需要在配置中解決這一問題
解決方案是在插件commonjs裏進行配置

配置如下

commonjs({
    include: [
         'node_modules/**'
     ],
         exclude: [
             'node_modules/process-es6/**'
         ],
         namedExports: {
            'node_modules/react/index.js': ['Component', 'PureComponent', 'Fragment', 'Children', 'createElement']
        }              
}),

總結

本文簡單介紹了rollupjs針對js,sass所做的編譯處理,記錄在此,一是分享給需要的同學使用,二是方便自己後續回看。

使用場景
  • 想要快速配置開發組件
  • 要用ES6+語法開發
  • 代碼清潔,清理無用代碼(tree-shaking)

參考資料:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章