React、Web Components、Angular、jQueryは永遠に友達です。 ユニバーサルJavaScriptコンポーネント

画像

この記事では、使用できるユニバーサルJavaScriptコンポーネントの作成方法について説明します









なぜ誰がそれを必要とするのか



JavaScript開発の世界は非常に細分化されています。 人気のあるフレームワークは多数あり、そのほとんどは互いに完全に互換性がありません。 そのような状況では、特定のフレームワークを選択するJavaScriptコンポーネントおよびライブラリの開発者は、このフレームワークが使用しない非常に多くの対象者を自動的に拒否します。 これは深刻な問題であり、その解決策は記事で提案されています。







すべての実装方法



  1. Reactコンポーネントを書きましょう。
  2. Reactと同様に連携して動作するpreactおよびpreact-compat JavaScriptライブラリを使用し、サイズが20キロバイトの哀れな重量で、他のすべてのラッパーを作成します。
  3. Webpackを使用してアセンブリを構成します。


コンポーネントコードを書く



たとえば、このタイプのドーナツチャートを作成します。







ドーナツチャート







ここでは驚くべきことは何も表示されません-コードだけです。







import React from 'react'; export default class DonutChart extends React.Component { render() { const { radius, holeSize, text, value, total, backgroundColor, valueColor } = this.props; const r = radius * (1 - (1 - holeSize)/2); const width = radius * (1 - holeSize); const circumference = 2 * Math.PI * r; const strokeDasharray = ((value * circumference) / total) + ' ' + circumference; const transform = 'rotate(-90 ' + radius + ',' + radius + ')'; const fontSize = r * holeSize * 0.6; return ( <div style = {{ textAlign: 'center', fontFamily: 'sans-serif' }}> <svg width = {radius * 2 + 'px'} height = {radius * 2 + 'px'}> <circle r = {r + 'px'} cx = {radius + 'px'} cy = {radius + 'px'} transform = {transform} fill = 'none' stroke = {backgroundColor} strokeWidth = {width} /> <circle r = {r + 'px'} cx = {radius + 'px'} cy = {radius + 'px'} transform = {transform} fill = 'none' stroke = {valueColor} strokeWidth = {width} strokeDasharray = {strokeDasharray} /> <text x = {radius + 'px'} y = {radius + 'px' }dy = {fontSize/3 + 'px'} textAnchor = 'middle' fill = {valueColor} fontSize = {fontSize + 'px'} > {~~(value * 1000 / total) / 10}% </text> </svg> <div style = {{ marginTop: '10px' }}> {text} </div> </div> ); } } DonutChart.defaultProps = { holeSize : 0.8, radius : 65, backgroundColor : '#d1d8e7', valueColor : '#49649f' };
      
      





結果はどうあるべきか



コードペンコレクション







Webpackアセンブリを構成する



基本的なWebpack構成
 var webpack = require('webpack'); module.exports = { output: { path: './dist' }, resolve: { extensions: ['', '.js'], }, module: { loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', query: { presets: [ 'latest', 'stage-0', 'react' ], plugins: [ 'transform-react-remove-prop-types', 'transform-react-constant-elements' ] } } ] }, plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': "'production'" }), new webpack.optimize.DedupePlugin(), new webpack.optimize.OccurrenceOrderPlugin(), new webpack.optimize.AggressiveMergingPlugin(), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false }, comments: false, sourceMap: true, mangle: true, minimize: true }) ] };
      
      





package.jsonにスクリプトを追加してプロジェクトをビルドします


 "scripts": { "build:preact": "node ./scripts/build-as-preact-component.js", "build:react": "node ./scripts/build-as-react-component.js", "build:webcomponent": "node ./scripts/build-as-web-component.js", "build:vanila": "node ./scripts/build-as-vanila-component.js", "build:jquery": "node ./scripts/build-as-jquery-component", "build:angular": "node ./scripts/build-as-angular-component", "build": "npm run build:preact && npm run build:react && npm run build:webcomponent && npm run build:vanila && npm run build:jquery && npm run build:angular" }
      
      





WebコンポーネントのWebpackアセンブリとラッパー



基本的なWebpack構成およびビルドの変更
 var webpack = require('webpack'); var config = require('./webpack.config'); var statsConfig = require('./statsConfig'); config.resolve.alias = { 'react': 'preact-compat', 'react-dom': 'preact-compat' }; config.entry = './src/DonutChartWebComponent.js'; config.output.filename = 'DonutChartWebComponent.js'; webpack(config).run(function (err, stats) { console.log(stats.toString(statsConfig)); });
      
      





ラッパー



 import React from 'react'; import ReactDOM from 'react-dom'; import DonutChart from './DonutChart'; const proto = Object.create(HTMLElement.prototype, { attachedCallback: { value: function() { const mountPoint = document.createElement('span'); this.createShadowRoot().appendChild(mountPoint); const props = { radius : +this.getAttribute('radius') || undefined, holeSize : +this.getAttribute('hole-size') || undefined, text : this.getAttribute('text') || undefined, value : +this.getAttribute('value') || undefined, total : +this.getAttribute('total') || undefined, backgroundColor : this.getAttribute('background-color') || undefined, valueColor : this.getAttribute('value-color') || undefined }; ReactDOM.render(( <DonutChart {...props}/> ), mountPoint); } } }); document.registerElement('donut-chart', {prototype: proto});
      
      





使用例



 <donut-chart value="39.6" total="100" text="Hello Web Components"></donut-chart>
      
      





結果





WebpackビルドとAngularのラッパー



基本的なWebpack構成およびビルドの変更
 var webpack = require('webpack'); var config = require('./webpack.config'); var statsConfig = require('./statsConfig'); config.resolve.alias = { 'react': 'preact-compat', 'react-dom': 'preact-compat' }; config.entry = './src/DonutChartAngularComponent.js'; config.output.filename = 'DonutChartAngularComponent.js'; config.output.library = 'DonutChart'; config.output.libraryTarget = 'umd'; webpack(config).run(function (err, stats) { console.log(stats.toString(statsConfig)); });
      
      





ラッパー



 import React from 'react'; import ReactDOM from 'react-dom'; import DonutChart from './DonutChart'; const module = angular.module('future-charts-example', []); module.directive('donutChart', function() { return { restrict: 'E', link: function(scope, element, attrs) { const props = { radius : +attrs['radius'] || undefined, holeSize : +attrs['hole-size'] || undefined, text : attrs['text'] || undefined, value : +attrs['value'] || undefined, total : +attrs['total'] || undefined, backgroundColor : attrs['background-color'] || undefined, valueColor : attrs['value-color'] || undefined }; ReactDOM.render(( <DonutChart {...props}/> ), element[0]); } }; });
      
      





使用例



 <body ng-app="future-charts-example"> <donut-chart value="89.6" total="100" text="Hello Angular"></donut-chart> </body>
      
      





結果





jQueryのWebpackビルドとラッパー



基本的なWebpack構成およびビルドの変更
 var webpack = require('webpack'); var config = require('./webpack.config'); var statsConfig = require('./statsConfig'); config.resolve.alias = { 'react': 'preact-compat', 'react-dom': 'preact-compat' }; config.entry = './src/DonutChartJQueryComponent.js'; config.output.filename = 'DonutChartJQueryComponent.js'; config.output.library = 'DonutChart'; config.output.libraryTarget = 'umd'; webpack(config).run(function (err, stats) { console.log(stats.toString(statsConfig)); });
      
      





ラッパー



 import React from 'react'; import ReactDOM from 'react-dom'; import DonutChart from './DonutChart'; jQuery.fn.extend({ DonutChart: function(props) { this.each( function () { ReactDOM.render(( <DonutChart {...props}/> ), this); } ); } });
      
      





使用例



 $('#app').DonutChart({ value : 42.1, total : 100, text : 'Hello jQuery' });
      
      





結果





VanilaJSのWebpackアセンブリおよびラッパー(ネイティブ関数から使用)



基本的なWebpack構成およびビルドの変更
 var webpack = require('webpack'); var config = require('./webpack.config'); var statsConfig = require('./statsConfig'); config.resolve.alias = { 'react': 'preact-compat', 'react-dom': 'preact-compat' }; config.entry = './src/DonutChartVanilaComponent.js'; config.output.filename = 'DonutChartVanilaComponent.js'; config.output.library = 'DonutChart'; config.output.libraryTarget = 'umd'; webpack(config).run(function (err, stats) { console.log(stats.toString(statsConfig)); });
      
      





ラッパー



 import React from 'react'; import ReactDOM from 'react-dom'; import DonutChart from './DonutChart'; module.exports = function DonutChartVanilaComponent(mountPoint, props) { ReactDOM.render(( <DonutChart {...props}/> ), mountPoint); };
      
      





使用例



 DonutChart(document.getElementById('app'), { value : 57.4, total : 100, text : 'Hello Vanila' });
      
      





結果





React用のWebpackビルド



基本的なWebpack構成およびビルドの変更
 var webpack = require('webpack'); var config = require('./webpack.config'); var statsConfig = require('./statsConfig'); var react = { root: 'React', commonjs2: 'react', commonjs: 'react' }; var reactDom = { root: 'ReactDOM', commonjs2: 'react-dom', commonjs: 'react-dom' }; config.externals = { 'react': react, 'react-dom': reactDom }; config.entry = './src/DonutChartUMD.js'; config.output.filename = 'DonutChartReact.js'; config.output.library = 'DonutChart'; config.output.libraryTarget = 'umd'; webpack(config).run(function (err, stats) { console.log(stats.toString(statsConfig)); });
      
      





結果





Preact用のWebpackビルド



基本的なWebpack構成およびビルドの変更
 var webpack = require('webpack'); var config = require('./webpack.config'); var statsConfig = require('./statsConfig'); var preactCompat = { root: 'preactCompat', commonjs2: 'preact-compat', commonjs: 'preact-compat' }; config.externals = { 'react': preactCompat, 'react-dom': preactCompat }; config.entry = './src/DonutChartUMD.js'; config.output.filename = 'DonutChartPreact.js'; config.output.library = 'DonutChart'; config.output.libraryTarget = 'umd'; webpack(config).run(function (err, stats) { console.log(stats.toString(statsConfig)); });
      
      





結果





おわりに



各オプションの重量はどれくらいになりますか:







反応する プリアクト バニラス jQuery 角度 Webコンポーネント
コンポーネントコード(3kb) コンポーネントコード(3kb) コンポーネントコード(3kb) コンポーネントコード(3kb) コンポーネントコード(3kb) コンポーネントコード(3kb)
ラップ(1kb) ラップ(1kb) ラップ(1kb) ラップ(1kb)
preact.min.js(3kb) preact.min.js(3kb) preact.min.js(3kb) preact.min.js(3kb)
preact-compat.min.js(18kb) preact-compat.min.js(18kb) preact-compat.min.js(18kb) preact-compat.min.js(18kb)
3kb 3kb 25kb 25kb 25kb 25kb


他のフレームワークで、またはWebコンポーネントとしてReactコンポーネントを使用するための20キロバイトのオーバーヘッドは、優れた結果です。 何らかの種類のReactコンポーネントを開発している場合は、知っている-誰でも利用できるようにすることができる-それは非常に簡単です。 このチュートリアルが世界を少し良くし、JavaScript開発ユニバースのひどい断片化を減らすのに役立つことを願っています。







出典: GithubCodepenNPM








All Articles