亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

react組件從搭建腳手架到在npm發布的步驟實現

2019-11-19 12:18:11
字體:
來源:轉載
供稿:網友

最近公司給公司里架設了私有的npm倉庫,相應地也需要一個用來發布react組件用的腳手架,在這個過程中又又又又復習了一下webpack,在這里分享下腳手架搭建的過程。

首先,我們預期的腳手架具有如下功能

  • 開發組件時可以實時預覽
  • 對組件各種資源進行打包(js/css/圖片等)
  • 一鍵打包發布

1.創建項目

腳手架的名字暫時取react-simple-component-boilerplate。

首先創建一個新目錄用于放我們的文件:

mkdir react-simple-component-boilerplatecd react-simple-component-boilerplate

使用npm命令創建一個項目

npm init

接下來會提示你輸入項目的名稱、版本號、作者等,也可以一路回車,稍后修改。

這一步完成后,你的項目文件夾里應該有一個package.json文件了,這個文件保存了我們項目和組件的各種信息。

接下來創建如下的目錄結構

react-simple-component-boilerplate |-- config // webpack配置 |-- demo // 開發時預覽用 |-- dist // 打包結果 |-- src  // 源文件目錄  | -- assets // 存放圖片等媒體文件  | -- style // 存放樣式,項目使用的是less來編寫樣式

2.安裝依賴

既然我們要發布的是react組件,那依賴里肯定少不了react。

使用npm install安裝下面的依賴

npm install react react-dom --save

打包工具選擇的是webpack,下面是開發依賴,也需要一并安裝

 "devDependencies": { // babel用于將你寫的es6+的代碼轉換到es5 "@babel/cli": "^7.0.0", "@babel/core": "^7.0.0", "@babel/plugin-proposal-class-properties": "^7.0.0", // 用于支持class屬性 "@babel/plugin-proposal-decorators": "^7.0.0", // 支持decorator "@babel/plugin-transform-modules-commonjs": "^7.0.0", "@babel/plugin-transform-runtime": "^7.0.0", // 自動polyfill es5不支持的api特性 "@babel/preset-env": "^7.0.0", // 根據目標環境來按需轉碼 "@babel/preset-react": "^7.0.0", // 讓babel支持react語法 "babel-loader": "^8.0.0", "css-loader": "^1.0.0", "file-loader": "^2.0.0", "html-loader": "^0.4.4", "less-loader": "^4.1.0", // 使用less來編寫樣式 "mini-css-extract-plugin": "^0.5.0", // 將css提取成一個單獨的文件 "style-loader": "^0.23.0", "webpack": "^4.26.0", "webpack-cli": "^3.1.2", // webpack4之后需要額外安裝webpack-cli "webpack-dev-server": "^3.1.14", // 開發時預覽組件所用的服務,在文件變化時會自動刷新頁面 "webpack-merge": "^4.1.4" // 用于合并webpack配置 },

3.編寫組件

在/src目錄下新建一個index.js,這就是我們組件的入口文件了。

如果項目中要使用圖片、css等,分類放到assets、style文件夾下就好。

下面我們就在index.js中寫一個簡單的組件

/* src/index.js */import React from 'react';import './style/style.less'; // 使用less的情況import testPng from './assets/test.png'; // 使用圖片的情況export default class MyComponent extends Component { render(){  return (<div>A new Component</div>) }}

接下來,我們在/demo目錄下新建index.html和demo.js這兩個文件用于在開發組件時預覽組件效果。
index.html內容如下

<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>Title</title></head><body><div id="root"></div><script src="demo.bundle.js"></script></body></html>

在demo.js中,我們要使用一下剛剛寫的組件(位于/src/index.js)看一下效果,開發中這個demo.js文件會被打包成demo.bundle.js,就是在上面index.html中引用的js。

import React from 'react';import ReactDom from 'react-dom';import MyComponent from '../src/index'const Demo = () => { return <div> <h1>組件預覽:</h1> <MyComponent /> </div>}ReactDom.render(<Demo />, document.getElementById('root'));

4.配置webpack和babel

4.1 配置webpack

在/config下我們建立三個webpack配置文件

  • webpack.base.js
  • webpack.config.dev.js // 開發時的配置
  • webpack.config.prod.js // 打包發布時的配置

由于開發和發布打包時webpack的配置有一部分是公共而且重復的,我們把這部分的配置單獨拿出來放到webpack.base.js中。
首先是公共配置webpack.base.js:

module.exports = { module: { rules: [  { // 在webpack中使用babel需要babel-loader  test: //.js?$/,  loader: 'babel-loader',  exclude: '/node_modules/',  },  { // 用于加載組件或者css中使用的圖片  test: //.(jpg|jpeg|png|gif|cur|ico|svg)$/,  use: [{   loader: 'file-loader', options: {   name: "images/[name][hash:8].[ext]"   }  }]  } ] }}

下面是開發時所用的webpack配置,寫在webpack.config.dev.js中

const path = require('path');const merge = require('webpack-merge');const baseConfig = require('./webpack.base.js'); // 引用公共的配置const devConfig = { entry: './demo/demo.js', // 入口文件 mode: 'development', // 打包為開發模式 output: { filename: 'demo.bundle.js', // 輸出的文件名稱 path: path.resolve(__dirname, '../demo') // 輸出的文件目錄 }, devServer: { // 該字段用于配置webpack-dev-server contentBase: path.join(__dirname, '../demo'), compress: true, port: 9000, // 端口9000 open: true // 自動打開瀏覽器 }, module: { rules: [  { // 編譯less  test: //.less$/,  exclude: '/node_modules/',  use: [{   loader: 'style-loader'  }, {   loader: 'css-loader'  }, {   loader: 'less-loader'  }]  }, ] },}module.exports = merge(devConfig, baseConfig); // 將baseConfig和devConfig合并為一個配置

需要注意的是,等會使用webpack-dev-sevrer啟動開發服務時,并不會實際在demo文件夾下生成demo.bundle.js,打包好的文件是在內存中的,但并不影響我們使用。

下面是打包發布時所用的webpack配置,寫在webpack.config.prod.js中

const path = require('path');const merge = require('webpack-merge');const baseConfig = require('./webpack.base.js');const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 用于將組件的css打包成單獨的文件輸出到`dist`目錄中const devConfig = { entry: './src/index.js', mode: 'production', output: { path: path.resolve(__dirname, '../dist'), filename: 'index.js', // 輸出文件 libraryTarget: 'umd', // 采用通用模塊定義, 注意webpack到4.0為止依然不提供輸出es module的方法,所以輸出的結果必須使用npm安裝到node_modules里再用,不然會報錯 library: 'react-simple-component-boilerplate', // 庫名稱 libraryExport: 'default', // 兼容 ES6(ES2015) 的模塊系統、CommonJS 和 AMD 模塊規范 }, externals: { react: {  root: "React",  commonjs2: "react",  commonjs: "react",  amd: "react" }, "react-dom": {  root: "ReactDOM",  commonjs2: "react-dom",  commonjs: "react-dom",  amd: "react-dom" } }, module: { rules: [{  test: //.(le|c)ss$/,  use: [  MiniCssExtractPlugin.loader,  "css-loader",  {   loader: "less-loader",   options: {   sourceMap: false   }  }  ] } ] }, plugins: [ new MiniCssExtractPlugin({  filename: "main.min.css" // 提取后的css的文件名 }) ],}module.exports = merge(devConfig, baseConfig);

上面我們配置了externals字段,這一點非常重要。

externals定義了外部依賴。將react和react-dom添加進該字段,說明我們的組件將依賴外部的react和react-dom,這樣就可以避免把react和react-dom打包進去(不然組件會很大)

4.1 配置babel

我們需要用babel把我們的代碼編譯成es5版本。在項目根目錄新建一個.babelrc文件,輸入以下內容。

{ "presets": [ [  "@babel/preset-env",  {  "targets": "> 0.25%, not dead"  } ], "@babel/preset-react" ], "plugins": [ "@babel/plugin-transform-runtime", "@babel/plugin-transform-modules-commonjs", [  "@babel/plugin-proposal-decorators",  {  "legacy": true  } ], "@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-object-rest-spread" ]}

我們在presets其中使用了preset-env, 規定了輸出的代碼目標環境是份額大于0.25%的瀏覽器。另外由于我們的項目里使用了react,presets中就要加入preset-react。
同時,plugins配置了一些babel插件,用于支持裝飾器展開操作符等類內直接定義屬性等新的es特性。

4.3 配置啟動命令

我們再次回到項目根目錄下的package.json中,編輯如下

 "scripts": { "build": "set NODE_ENV=production && webpack --config ./config/webpack.config.prod.js", "pub": "npm run build && npm publish", "dev": "webpack-dev-server --config ./config/webpack.config.dev.js" }, "main": "dist/index.js", "files": ["dist"]
  • build 命令用于打包組件
  • dev 命令會使用webpack-dev-server啟動一個開發服務用于預覽組件效果
  • pub 命令進行打包組件并且發布到npm上
  • main字段指定了我們的組件的入口文件,files字段用于指定我們的npm包的文件目錄。

5.試用和發布

要發布一個npm包,我們需使用如下命令添加一個npm的賬號,如果已經添加過的這一步可以跳過。

npm adduser

如果已經有npm賬號,可以使用npm login登陸。

如果不知道自己是否已經添加過了npm賬號,使用npm whoami查看登陸信息即可

接下來就編輯package.json把組件的名稱/版本/介紹等字段都填寫一下。

好了,接下我們先使用npm run dev命令,此時會自動打開默認瀏覽器預覽組件。

如果沒什么問題的話,接下來使用npm run pub進行打包和發布。

等待發布完成后,我們就下載安裝一下。

npm i your-component // 假設你的包名字叫your-component

使用自己發布的組件

import YourComponent from 'your-component';import 'your-component/dist/main.min.css'; // 如果給組件寫了樣式,需要手動導入css文件

6.總結

到這里,一個非常非常簡單的用于發布react小組件的腳手架就搭好了,總結一下其中要注意的地方:

  • webpack打包時libraryTarget要使用umd
  • externals 里要把外部依賴配置好
  • 如果還要生成es module,可以額外使用gulp或rollup等工具
  • webpack4 之后建議使用MiniCssExtractPlugin來提取css

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产欧美日韩免费看aⅴ视频| 国产精品大陆在线观看| 日韩中文字幕精品视频| 国产亚洲精品美女久久久| 久久精品中文字幕电影| 亚洲天堂开心观看| 色播久久人人爽人人爽人人片视av| 欧美国产第二页| 欧美亚洲在线观看| 亚洲一区二区三区sesese| 日韩精品999| 亚洲一区亚洲二区亚洲三区| 国产精品久久久久久久7电影| 久久av中文字幕| 69久久夜色精品国产7777| 国模极品一区二区三区| 亚洲字幕在线观看| 国产视频欧美视频| 国产国语videosex另类| 欧美日韩国产精品一区二区三区四区| 伦理中文字幕亚洲| 国产脚交av在线一区二区| 中文字幕国产亚洲2019| 日本精品中文字幕| 97精品在线观看| 欧美日韩成人黄色| 国产精品自拍偷拍| www.亚洲人.com| 中文字幕日韩欧美| 日本精品久久电影| 2019中文字幕全在线观看| 国产成人自拍视频在线观看| 欧美又大又硬又粗bbbbb| 亚洲综合大片69999| 亚洲国产另类久久精品| 久久久噜久噜久久综合| 亚洲精品一区中文字幕乱码| 亚洲网站视频福利| 久久久999精品视频| 亚洲最新av网址| 97在线视频观看| 欧美成人免费va影院高清| 最近2019中文免费高清视频观看www99| 96国产粉嫩美女| 日韩福利在线播放| 蜜臀久久99精品久久久无需会员| 日韩一区二区av| 欧美做受高潮电影o| 欧美中文字幕视频| 国产日韩欧美电影在线观看| 欧美精品久久久久久久久| 亚洲欧美日韩一区二区三区在线| 亚洲欧美日韩天堂一区二区| 亚洲精品欧美日韩专区| 欧美激情在线有限公司| 欧美另类老肥妇| 57pao成人国产永久免费| 日韩福利视频在线观看| 国产精品九九九| 狠狠躁18三区二区一区| 国产精品极品美女粉嫩高清在线| 亚洲精品国产精品自产a区红杏吧| 亚洲xxxx妇黄裸体| 日韩av手机在线观看| 中文字幕av一区二区三区谷原希美| 国产一区二区三区毛片| 亚洲欧美另类在线观看| 欧美另类在线播放| 国产一区二中文字幕在线看| 国产精品美女主播在线观看纯欲| 欧美一区二区大胆人体摄影专业网站| 日本精品视频在线播放| 国产精品ⅴa在线观看h| 黑人欧美xxxx| 日韩精品在线视频观看| 亚洲欧美色图片| 91在线免费看网站| 亚洲一区制服诱惑| 国产免费亚洲高清| 国产精品无av码在线观看| 欧美亚洲成人网| 亚洲综合精品一区二区| 欧洲亚洲女同hd| 久久久久久12| 日韩免费电影在线观看| 亚洲欧美日韩久久久久久| 日韩一区二区av| 日韩黄在线观看| 欧美乱大交xxxxx另类电影| 亚洲午夜久久久久久久| 亚洲精品少妇网址| 精品综合久久久久久97| 亚洲美女av在线| 国产精品九九久久久久久久| 亚洲欧洲国产一区| 精品二区三区线观看| 岛国av一区二区在线在线观看| 国产精品色视频| 欧美麻豆久久久久久中文| 欧美亚洲视频在线观看| 国外成人在线播放| 欧美午夜精品久久久久久久| 亚洲欧美日韩精品久久亚洲区| 国外成人免费在线播放| 欧美韩国理论所午夜片917电影| 久久久国产一区二区三区| 最新国产精品拍自在线播放| 91欧美精品成人综合在线观看| 国产精品日韩精品| 国产精品扒开腿做爽爽爽的视频| 国产美女搞久久| 国产午夜精品全部视频在线播放| 日韩电影免费观看在线| 色yeye香蕉凹凸一区二区av| 精品高清一区二区三区| 国产精品久久99久久| 国外视频精品毛片| 久久午夜a级毛片| 欧美激情精品久久久久久大尺度| 琪琪亚洲精品午夜在线| 亚洲精品一区二区三区不| 亚洲人成自拍网站| 国模精品一区二区三区色天香| 国产精品va在线| 国产精品女主播| 精品一区二区亚洲| 亚洲国产99精品国自产| 欧美日韩国产999| 成人久久精品视频| 亚洲毛片在线看| 国产精品自拍网| 欧美人在线观看| 亚洲一区二区黄| 精品美女永久免费视频| 亚洲精品一区二三区不卡| 精品国产乱码久久久久久婷婷| 精品视频偷偷看在线观看| 欧美国产精品va在线观看| 亚洲999一在线观看www| 91性高湖久久久久久久久_久久99| 欧美黄色小视频| 精品欧美aⅴ在线网站| 国产91色在线|免| 亚洲第一页在线| 亚洲a∨日韩av高清在线观看| 日本精品久久久久久久| 蜜臀久久99精品久久久久久宅男| 91视频免费网站| 91天堂在线观看| 亚洲国产精品小视频| 91av在线不卡| 美女扒开尿口让男人操亚洲视频网站| 97精品一区二区视频在线观看| 亚洲第一网站免费视频| 日韩av在线免播放器| 亚洲一区二区福利| 国语自产精品视频在线看| 日韩精品在线影院| 中文字幕综合一区| 91久久国产综合久久91精品网站| 尤物精品国产第一福利三区| 欧美日韩中文字幕在线| 欧美日韩在线视频一区| 亚洲欧美日韩直播|