├── .babelrc ├── .github └── workflows │ ├── component.yaml │ └── publish.yaml ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── conf ├── ampExtensionList.json └── constants.json ├── examples ├── css-modules │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── components │ │ │ ├── Application.css │ │ │ └── Application.js │ │ ├── server-dev.js │ │ └── server.js │ ├── webpack.config.dev.js │ └── webpack.config.js ├── external-amp-component │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── components │ │ │ ├── Application.css │ │ │ └── Application.js │ │ ├── server-dev.js │ │ └── server.js │ ├── webpack.config.dev.js │ └── webpack.config.js ├── global-scoped-css │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── components │ │ │ └── Application.js │ │ ├── server-dev.js │ │ ├── server.js │ │ └── styles │ │ │ └── global.css │ ├── webpack.config.dev.js │ └── webpack.config.js ├── multiple-pages │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── components │ │ │ ├── Page1.js │ │ │ └── Page2.js │ │ ├── server-dev.js │ │ ├── server.js │ │ └── styles │ │ │ └── global.css │ ├── webpack.config.dev.js │ └── webpack.config.js ├── redux │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── components │ │ │ ├── Application.css │ │ │ ├── Application.js │ │ │ └── Root.js │ │ ├── containers │ │ │ └── Application.js │ │ ├── server-dev.js │ │ └── server.js │ ├── webpack.config.dev.js │ └── webpack.config.js └── styled-components │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── components │ │ └── Application.js │ ├── server-dev.js │ ├── server.js │ └── styles │ │ └── global.css │ ├── webpack.config.dev.js │ └── webpack.config.js ├── index.js ├── lib ├── AmpHtmlRendererBuilder.js └── HtmlComponentBuilder.js ├── package-lock.json ├── package.json ├── tests └── extensionComponents │ ├── amp-3q-player │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-3q-player.test.js.snap │ └── render-amp-3q-player.test.js │ ├── amp-access-laterpay │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-access-laterpay.test.js.snap │ └── render-amp-access-laterpay.test.js │ ├── amp-access │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-access.test.js.snap │ └── render-amp-access.test.js │ ├── amp-accordion │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-accordion.test.js.snap │ └── render-amp-accordion.test.js │ ├── amp-ad │ ├── Application.css │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-ad.test.js.snap │ └── render-amp-ad.test.js │ ├── amp-addthis │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-addthis.test.js.snap │ └── render-amp-addthis.test.js │ ├── amp-analytics │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-analytics.test.js.snap │ └── render-amp-analytics.test.js │ ├── amp-anim │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-anim.test.js.snap │ └── render-amp-anim.test.js │ ├── amp-animation │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-animation.test.js.snap │ └── render-amp-animation.test.js │ ├── amp-apester-media │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-apester-media.test.js.snap │ └── render-amp-apester-media.test.js │ ├── amp-app-banner │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-app-banner.test.js.snap │ └── render-amp-app-banner.test.js │ ├── amp-audio │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-audio.test.js.snap │ └── render-amp-audio.test.js │ ├── amp-auto-ads │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-auto-ads.test.js.snap │ └── render-amp-auto-ads.test.js │ ├── amp-beopinion │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-beopinion.test.js.snap │ └── render-amp-beopinion.test.js │ ├── amp-bind │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-state.test.js.snap │ └── render-amp-state.test.js │ ├── amp-bodymovin-animation │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-bodymovin-animation.test.js.snap │ └── render-amp-bodymovin-animation.test.js │ ├── amp-brid-player │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-brid-player.test.js.snap │ └── render-amp-brid-player.test.js │ ├── amp-brightcove │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-brightcove.test.js.snap │ └── render-amp-brightcove.test.js │ ├── amp-byside-content │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-byside-content.test.js.snap │ └── render-amp-byside-content.test.js │ ├── amp-call-tracking │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-call-tracking.test.js.snap │ └── render-amp-call-tracking.test.js │ ├── amp-carousel │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-carousel.test.js.snap │ └── render-amp-carousel.test.js │ ├── amp-consent │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-consent.test.js.snap │ └── render-amp-consent.test.js │ ├── amp-dailymotion │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-dailymotion.test.js.snap │ └── render-amp-dailymotion.test.js │ ├── amp-date-picker │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-date-picker.test.js.snap │ └── render-amp-date-picker.test.js │ ├── amp-experiment │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-experiment.test.js.snap │ └── render-amp-experiment.test.js │ ├── amp-facebook-comments │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-facebook-comments.test.js.snap │ └── render-amp-facebook-comments.test.js │ ├── amp-facebook-like │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-facebook-like.test.js.snap │ └── render-amp-facebook-like.test.js │ ├── amp-facebook-page │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-facebook-page.test.js.snap │ └── render-amp-facebook-page.test.js │ ├── amp-facebook │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-facebook.test.js.snap │ └── render-amp-facebook.test.js │ ├── amp-fit-text │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-fit-text.test.js.snap │ └── render-amp-fit-text.test.js │ ├── amp-font │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-font.test.js.snap │ └── render-amp-font.test.js │ ├── amp-form │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-form.test.js.snap │ └── render-amp-form.test.js │ ├── amp-fx-collection │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-fx-collection.test.js.snap │ └── render-amp-fx-collection.test.js │ ├── amp-fx-flying-carpet │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-fx-flying-carpet.test.js.snap │ └── render-amp-fx-flying-carpet.test.js │ ├── amp-geo │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-geo.test.js.snap │ └── render-amp-geo.test.js │ ├── amp-gfycat │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-gfycat.test.js.snap │ └── render-amp-gfycat.test.js │ ├── amp-gist │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-gist.test.js.snap │ └── render-amp-gist.test.js │ ├── amp-hulu │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-hulu.test.js.snap │ └── render-amp-hulu.test.js │ ├── amp-iframe │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-iframe.test.js.snap │ └── render-amp-iframe.test.js │ ├── amp-ima-video │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-ima-video.test.js.snap │ └── render-amp-ima-video.test.js │ ├── amp-image-lightbox │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-image-lightbox.test.js.snap │ └── render-amp-image-lightbox.test.js │ ├── amp-imgur │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-imgur.test.js.snap │ └── render-amp-imgur.test.js │ ├── amp-instagram │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-instagram.test.js.snap │ └── render-amp-instagram.test.js │ ├── amp-install-serviceworker │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-install-serviceworker.test.js.snap │ └── render-amp-install-serviceworker.test.js │ ├── amp-izlesene │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-izlesene.test.js.snap │ └── render-amp-izlesene.test.js │ ├── amp-jwplayer │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-jwplayer.test.js.snap │ └── render-amp-jwplayer.test.js │ ├── amp-kaltura-player │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-kaltura-player.test.js.snap │ └── render-amp-kaltura-player.test.js │ ├── amp-lightbox-gallery │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-lightbox-gallery.test.js.snap │ └── render-amp-lightbox-gallery.test.js │ ├── amp-lightbox │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-lightbox.test.js.snap │ └── render-amp-lightbox.test.js │ ├── amp-list │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-list.test.js.snap │ └── render-amp-list.test.js │ ├── amp-live-list │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-live-list.test.js.snap │ └── render-amp-live-list.test.js │ ├── amp-mathml │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-mathml.test.js.snap │ └── render-amp-mathml.test.js │ ├── amp-mustache │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-mustache.test.js.snap │ └── render-amp-mustache.test.js │ ├── amp-nexxtv-player │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-nexxtv-player.test.js.snap │ └── render-amp-nexxtv-player.test.js │ ├── amp-o2-player │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-o2-player.test.js.snap │ └── render-amp-o2-player.test.js │ ├── amp-ooyala-player │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-ooyala-player.test.js.snap │ └── render-amp-ooyala-player.test.js │ ├── amp-pinterest │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-pinterest.test.js.snap │ └── render-amp-pinterest.test.js │ ├── amp-playbuzz │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-playbuzz.test.js.snap │ └── render-amp-playbuzz.test.js │ ├── amp-position-observer │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-position-observer.test.js.snap │ └── render-amp-position-observer.test.js │ ├── amp-reach-player │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-reach-player.test.js.snap │ └── render-amp-reach-player.test.js │ ├── amp-reddit │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-reddit.test.js.snap │ └── render-amp-reddit.test.js │ ├── amp-riddle-quiz │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-riddle-quiz.test.js.snap │ └── render-amp-riddle-quiz.test.js │ ├── amp-selector │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-selector.test.js.snap │ └── render-amp-selector.test.js │ ├── amp-sidebar │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-sidebar.test.js.snap │ └── render-amp-sidebar.test.js │ ├── amp-social-share │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-social-share.test.js.snap │ └── render-amp-social-share.test.js │ ├── amp-soundcloud │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-soundcloud.test.js.snap │ └── render-amp-soundcloud.test.js │ ├── amp-springboard-player │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-springboard-player.test.js.snap │ └── render-amp-springboard-player.test.js │ ├── amp-sticky-ad │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-sticky-ad.test.js.snap │ └── render-amp-sticky-ad.test.js │ ├── amp-story │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-story.test.js.snap │ └── render-amp-story.test.js │ ├── amp-timeago │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-timeago.test.js.snap │ └── render-amp-timeago.test.js │ ├── amp-twitter │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-twitter.test.js.snap │ └── render-amp-twitter.test.js │ ├── amp-user-notification │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-user-notification.test.js.snap │ └── render-amp-user-notification.test.js │ ├── amp-video │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-video.test.js.snap │ └── render-amp-video.test.js │ ├── amp-vimeo │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-vimeo.test.js.snap │ └── render-amp-vimeo.test.js │ ├── amp-vine │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-vine.test.js.snap │ └── render-amp-vine.test.js │ ├── amp-vk │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-vk.test.js.snap │ └── render-amp-vk.test.js │ ├── amp-web-push │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-web-push.test.js.snap │ └── render-amp-web-push.test.js │ ├── amp-wistia-player │ ├── Application.js │ ├── __snapshots__ │ │ └── render-amp-wistia-player.test.js.snap │ └── render-amp-wistia-player.test.js │ └── amp-youtube │ ├── Application.js │ ├── __snapshots__ │ └── render-amp-youtube.test.js.snap │ └── render-amp-youtube.test.js └── webpack.test.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/react", 4 | ["@babel/env", { 5 | "targets": { 6 | "node": "10" 7 | } 8 | }] 9 | ], 10 | "env": { 11 | "test": { 12 | "presets": [ 13 | "@babel/react", 14 | ["@babel/env", { 15 | "targets": { 16 | "node": "10" 17 | } 18 | }] 19 | ], 20 | "plugins": [ 21 | [ 22 | "css-modules-transform", { 23 | "generateScopedName": "[name]__[local]___[hash:base64:5]", 24 | "extensions": [".css"] 25 | } 26 | ] 27 | ] 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /.github/workflows/component.yaml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Component Build 5 | 6 | on: 7 | push: 8 | branches: [ main ] 9 | pull_request: 10 | branches: [ main ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [14.x, 16.x] 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: Use Node.js ${{ matrix.node-version }} 24 | uses: actions/setup-node@v2 25 | with: 26 | node-version: ${{ matrix.node-version }} 27 | cache: 'npm' 28 | - run: npm ci 29 | - run: npm run build --if-present 30 | - run: npm run test -------------------------------------------------------------------------------- /.github/workflows/publish.yaml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Npm Publish 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Use Node.js ${{ matrix.node-version }} 18 | uses: actions/setup-node@v2 19 | with: 20 | node-version: '14.x' 21 | registry-url: 'https://registry.npmjs.org' 22 | - run: npm ci 23 | - run: npm run build --if-present 24 | - run: npm run test 25 | - run: npm publish 26 | env: 27 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /coverage 2 | /dist 3 | /node_modules 4 | npm-debug.log* 5 | index-compiled.js 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | examples/ 2 | coverage/ 3 | dist/ 4 | tests/ 5 | .babelrc 6 | .gitignore 7 | README.md 8 | webpack.test.config.js 9 | yarn.lock 10 | package-lock.json 11 | index.js 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Jimmy Tseng and other contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /conf/constants.json: -------------------------------------------------------------------------------- 1 | { 2 | "AMP_CDN_HOST": "https://cdn.ampproject.org", 3 | "EXT_SCRIPT_SRC_PREFIX": "https://cdn.ampproject.org/v0/", 4 | "AMP_BOILERPLATE_CODE": "", 5 | "HTML_RENDERER_FILE_NAME": "AmpHtmlRenderer.js", 6 | "HTML_COMPONENT_FILE_NAME": "Html.amp.js", 7 | "HTML_COMPONENT_CSS_FILE_NAME": "Html.amp.css" 8 | } -------------------------------------------------------------------------------- /examples/css-modules/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/env", "@babel/react"], 3 | "env": { 4 | "production": { 5 | "presets": ["@babel/env", "@babel/react"], 6 | "plugins": [ 7 | [ 8 | "css-modules-transform", { 9 | "generateScopedName": "[name]__[local]___[hash:base64:5]", 10 | "extensions": [".css"] 11 | } 12 | ] 13 | ] 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /examples/css-modules/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | bundle/ 4 | -------------------------------------------------------------------------------- /examples/css-modules/README.md: -------------------------------------------------------------------------------- 1 | # Example: Build AMP page with React + CSS modules 2 | 3 | ## Quick Start 4 | 5 | ### Dependencies Installation 6 | 7 | ``` 8 | $ npm i 9 | ``` 10 | 11 | ### Development Mode 12 | 13 | ``` 14 | $ npm run dev 15 | ``` 16 | 17 | Now a valid AMP page - `http://localhost:3000/` is available. 18 | 19 | ### Prouction Mode 20 | 21 | ``` 22 | $ npm run build 23 | ``` 24 | 25 | ``` 26 | $ npm start 27 | ``` 28 | -------------------------------------------------------------------------------- /examples/css-modules/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-css-modules", 3 | "version": "1.0.0", 4 | "description": "This is a example of using amp-react-renderer-plugin in React + css-modules project", 5 | "main": "index.js", 6 | "author": "CR Jimmy ", 7 | "license": "MIT", 8 | "dependencies": { 9 | "express": "^4.16.3", 10 | "react": "^16.8.6", 11 | "react-dom": "^16.8.6" 12 | }, 13 | "devDependencies": { 14 | "@babel/cli": "^7.4.4", 15 | "@babel/core": "^7.4.5", 16 | "@babel/preset-env": "^7.4.5", 17 | "@babel/preset-react": "^7.0.0", 18 | "@babel/register": "^7.4.4", 19 | "babel-loader": "^8.0.x", 20 | "babel-plugin-css-modules-transform": "^1.5.0", 21 | "css-loader": "^2.x.x", 22 | "mini-css-extract-plugin": "^0.6.0", 23 | "nodemon": "^1.17.3", 24 | "webpack": "^4.30.0", 25 | "webpack-dev-middleware": "^3.6.2", 26 | "write-file-webpack-plugin": "^4.2.0" 27 | }, 28 | "scripts": { 29 | "start": "NODE_ENV=production node ./dist/server.js", 30 | "build": "BABEL_ENV=production ./node_modules/@babel/cli/bin/babel.js src/ --out-dir dist --copy-files && webpack", 31 | "dev": "nodemon --watch src --ignore src/AmpReactRenderer src/server-dev.js" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/css-modules/src/components/Application.css: -------------------------------------------------------------------------------- 1 | .blue-box, .red-box, .green-box { 2 | width: 100%; 3 | height: 280px; 4 | } 5 | 6 | .blue-box { 7 | background: blue; 8 | } 9 | 10 | .red-box { 11 | background: red; 12 | } 13 | 14 | .green-box { 15 | background: green; 16 | } 17 | -------------------------------------------------------------------------------- /examples/css-modules/src/components/Application.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import style from './Application.css' 3 | 4 | const Application = () => { 5 | return ( 6 |
7 |

Create AMP app, the React way

8 | 11 |
12 |
13 | This is a blue box. 14 |
15 |
16 |
17 | This is a red box. 18 |
19 |
20 |
21 | This is a green box. 22 |
23 | 24 | 28 |
29 | ) 30 | } 31 | 32 | export default Application 33 | -------------------------------------------------------------------------------- /examples/css-modules/src/server-dev.js: -------------------------------------------------------------------------------- 1 | require('@babel/register')({ 2 | babelrc: false, 3 | presets: ['@babel/react', '@babel/env'], 4 | plugins: [[ 5 | 'css-modules-transform', { 6 | 'generateScopedName': '[name]__[local]___[hash:base64:5]', 7 | 'extensions': ['.css'] 8 | } 9 | ]] 10 | }) 11 | 12 | const webpackConfig = require('../webpack.config.dev.js') 13 | const webpackDevMiddleware = require('webpack-dev-middleware') 14 | const webpack = require('webpack') 15 | const compiler = webpack(webpackConfig) 16 | const server = require('./server.js') 17 | 18 | // apply webpack dev middleware to enable Amp Html Renderer auto rebuilding 19 | server.use(webpackDevMiddleware(compiler)) 20 | 21 | server.listen(3000, () => console.log('Example app listening on port 3000!')) 22 | -------------------------------------------------------------------------------- /examples/css-modules/src/server.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const express = require('express') 3 | const React = require('react') 4 | const Application = require('./components/Application.js').default 5 | 6 | const server = express() 7 | 8 | server.get('/', (req, res) => { 9 | const ampHtmlRenderer = require('../bundle/AmpHtmlRenderer.js') 10 | 11 | res.send( 12 | ampHtmlRenderer({ 13 | entryName: 'home', 14 | AppComponent: , 15 | title: 'This is my first AMP page powered by React + CSS modules', 16 | canonical: 'https://jimmy.amp.com', 17 | headComponents: null 18 | }) 19 | ) 20 | }) 21 | 22 | if (process.env.NODE_ENV === 'production') { 23 | server.listen(3000, () => console.log('Example app listening on port 3000!')) 24 | } else { 25 | module.exports = server 26 | } 27 | -------------------------------------------------------------------------------- /examples/css-modules/webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') 3 | const WriteFilePlugin = require('write-file-webpack-plugin') 4 | const AmpReactRendererPlugin = require('../../index-compiled') 5 | 6 | module.exports = { 7 | mode: 'development', 8 | entry: { 9 | home: path.resolve(__dirname, './src/components/Application.js') 10 | }, 11 | output: { 12 | filename: '[name].js', 13 | path: path.resolve(__dirname, 'bundle') 14 | }, 15 | module: { 16 | rules: [ 17 | { 18 | test: /\.js$/, 19 | use: 'babel-loader' 20 | }, 21 | { 22 | test: /\.css$/, 23 | use: [ 24 | { 25 | loader: MiniCssExtractPlugin.loader 26 | }, 27 | { 28 | loader: 'css-loader', 29 | query: { 30 | modules: true, 31 | localIdentName: '[name]__[local]___[hash:base64:5]' 32 | } 33 | } 34 | ] 35 | } 36 | ] 37 | }, 38 | plugins: [ 39 | new MiniCssExtractPlugin({ 40 | // Options similar to the same options in webpackOptions.output 41 | // both options are optional 42 | filename: '[name].css', 43 | chunkFilename: '[id].css', 44 | }), 45 | new AmpReactRendererPlugin(), 46 | new WriteFilePlugin() 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /examples/css-modules/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') 3 | const AmpReactRendererPlugin = require('../../index-compiled') 4 | 5 | module.exports = { 6 | mode: 'development', 7 | entry: { 8 | home: path.resolve(__dirname, './src/components/Application.js') 9 | }, 10 | output: { 11 | filename: '[name].js', 12 | path: path.resolve(__dirname, 'bundle') 13 | }, 14 | module: { 15 | rules: [ 16 | { 17 | test: /\.js$/, 18 | use: 'babel-loader' 19 | }, 20 | { 21 | test: /\.css$/, 22 | use: [ 23 | { 24 | loader: MiniCssExtractPlugin.loader 25 | }, 26 | { 27 | loader: 'css-loader', 28 | query: { 29 | modules: true, 30 | localIdentName: '[name]__[local]___[hash:base64:5]' 31 | } 32 | } 33 | ] 34 | } 35 | ] 36 | }, 37 | plugins: [ 38 | new MiniCssExtractPlugin({ 39 | // Options similar to the same options in webpackOptions.output 40 | // both options are optional 41 | filename: '[name].css', 42 | chunkFilename: '[id].css', 43 | }), 44 | new AmpReactRendererPlugin() 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /examples/external-amp-component/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/env", "@babel/react"], 3 | "env": { 4 | "production": { 5 | "presets": ["@babel/env", "@babel/react"], 6 | "plugins": [ 7 | [ 8 | "css-modules-transform", { 9 | "generateScopedName": "[name]__[local]___[hash:base64:5]", 10 | "extensions": [".css"] 11 | } 12 | ] 13 | ] 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /examples/external-amp-component/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | bundle/ 4 | -------------------------------------------------------------------------------- /examples/external-amp-component/README.md: -------------------------------------------------------------------------------- 1 | # Example: Build AMP page with external shared component 2 | 3 | ## Quick Start 4 | 5 | ### Dependencies Installation 6 | 7 | ``` 8 | $ npm i 9 | ``` 10 | 11 | ### Development Mode 12 | 13 | ``` 14 | $ npm run dev 15 | ``` 16 | 17 | Now a valid AMP page - `http://localhost:3000/` is available 18 | 19 | ### Prouction Mode 20 | 21 | ``` 22 | $ npm run build 23 | ``` 24 | 25 | ``` 26 | $ npm start 27 | ``` 28 | -------------------------------------------------------------------------------- /examples/external-amp-component/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-css-modules", 3 | "version": "1.0.0", 4 | "description": "This is a example of using amp-react-renderer-plugin with external shared component", 5 | "main": "index.js", 6 | "author": "CR Jimmy ", 7 | "license": "MIT", 8 | "dependencies": { 9 | "amp-react-square-img": "0.0.5", 10 | "express": "^4.16.3", 11 | "react": "^16.8.6", 12 | "react-dom": "^16.8.6" 13 | }, 14 | "devDependencies": { 15 | "@babel/cli": "^7.4.4", 16 | "@babel/core": "^7.4.5", 17 | "@babel/preset-env": "^7.4.5", 18 | "@babel/preset-react": "^7.0.0", 19 | "@babel/register": "^7.4.4", 20 | "amp-react-renderer-plugin": "^0.1.0", 21 | "babel-loader": "^8.x.x", 22 | "babel-plugin-css-modules-transform": "^1.5.0", 23 | "css-loader": "2.x.x", 24 | "mini-css-extract-plugin": "^0.6.0", 25 | "nodemon": "^1.17.3", 26 | "webpack": "^4.30.0", 27 | "webpack-dev-middleware": "^3.6.2", 28 | "write-file-webpack-plugin": "^4.2.0" 29 | }, 30 | "scripts": { 31 | "start": "NODE_ENV=production node ./dist/server.js", 32 | "build": "BABEL_ENV=production ./node_modules/@babel/cli/bin/babel.js src/ --out-dir dist --copy-files && webpack", 33 | "dev": "nodemon --watch src --ignore src/AmpReactRenderer src/server-dev.js" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /examples/external-amp-component/src/components/Application.css: -------------------------------------------------------------------------------- 1 | .blue-box, .red-box, .green-box { 2 | width: 100%; 3 | height: 280px; 4 | } 5 | 6 | .blue-box { 7 | background: blue; 8 | } 9 | 10 | .red-box { 11 | background: red; 12 | } 13 | 14 | .green-box { 15 | background: green; 16 | } 17 | -------------------------------------------------------------------------------- /examples/external-amp-component/src/components/Application.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import SquareImage, { statics } from 'amp-react-square-img' 3 | import 'amp-react-square-img/dist/css/SquareImage.css' 4 | 5 | const Application = () => { 6 | return ( 7 |
8 |

Create AMP app with shared external component

9 | 13 |
14 | ) 15 | } 16 | 17 | export default Application 18 | -------------------------------------------------------------------------------- /examples/external-amp-component/src/server-dev.js: -------------------------------------------------------------------------------- 1 | require('@babel/register')({ 2 | babelrc: false, 3 | presets: ['@babel/react', '@babel/env'], 4 | plugins: [[ 5 | 'css-modules-transform', { 6 | 'generateScopedName': '[name]__[local]___[hash:base64:5]', 7 | 'extensions': ['.css'] 8 | } 9 | ]] 10 | }) 11 | 12 | const webpackConfig = require('../webpack.config.dev.js') 13 | const webpackDevMiddleware = require('webpack-dev-middleware') 14 | const webpack = require('webpack') 15 | const compiler = webpack(webpackConfig) 16 | const server = require('./server.js') 17 | 18 | // apply webpack dev middleware to enable Amp Html Renderer auto rebuilding 19 | server.use(webpackDevMiddleware(compiler)) 20 | 21 | server.listen(3000, () => console.log('Example app listening on port 3000!')) 22 | -------------------------------------------------------------------------------- /examples/external-amp-component/src/server.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const express = require('express') 3 | const React = require('react') 4 | const Application = require('./components/Application.js').default 5 | 6 | const server = express() 7 | 8 | server.get('/', (req, res) => { 9 | const ampHtmlRenderer = require('../bundle/AmpHtmlRenderer.js') 10 | 11 | res.send( 12 | ampHtmlRenderer({ 13 | entryName: 'home', 14 | AppComponent: , 15 | title: 'This is my first AMP page powered by React + CSS modules', 16 | canonical: 'https://jimmy.amp.com', 17 | headComponents: null 18 | }) 19 | ) 20 | }) 21 | 22 | if (process.env.NODE_ENV === 'production') { 23 | server.listen(3000, () => console.log('Example app listening on port 3000!')) 24 | } else { 25 | module.exports = server 26 | } 27 | -------------------------------------------------------------------------------- /examples/external-amp-component/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') 3 | const AmpReactRendererPlugin = require('../../index-compiled') 4 | 5 | module.exports = { 6 | mode: 'development', 7 | devtool: 'cheap-module-eval-source-map', 8 | entry: { 9 | home: path.resolve(__dirname, './src/components/Application.js') 10 | }, 11 | output: { 12 | filename: '[name].js', 13 | path: path.resolve(__dirname, 'bundle') 14 | }, 15 | module: { 16 | rules: [ 17 | { 18 | test: /\.js$/, 19 | use: 'babel-loader' 20 | }, 21 | { 22 | test: /\.css$/, 23 | exclude: /(statics\/css\/[^/]+|node_modules\/.+)\.css$/, 24 | use: [ 25 | { 26 | loader: MiniCssExtractPlugin.loader 27 | }, 28 | { 29 | loader: 'css-loader', 30 | query: { 31 | modules: true, 32 | localIdentName: '[name]__[local]___[hash:base64:5]' 33 | } 34 | } 35 | ] 36 | }, 37 | { 38 | test: /node_modules\/.+\.css$/, 39 | use: [ 40 | { 41 | loader: MiniCssExtractPlugin.loader 42 | }, 43 | { 44 | loader: 'css-loader' 45 | } 46 | ] 47 | } 48 | ] 49 | }, 50 | plugins: [ 51 | new MiniCssExtractPlugin({ 52 | // Options similar to the same options in webpackOptions.output 53 | // both options are optional 54 | filename: '[name].css', 55 | chunkFilename: '[id].css', 56 | }), 57 | new AmpReactRendererPlugin() 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /examples/global-scoped-css/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/env", "@babel/react"] 3 | } -------------------------------------------------------------------------------- /examples/global-scoped-css/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | bundle/ 4 | -------------------------------------------------------------------------------- /examples/global-scoped-css/README.md: -------------------------------------------------------------------------------- 1 | # Example: Build AMP page with React + global scoped css 2 | 3 | ## Quick Start 4 | 5 | ### Dependencies Installation 6 | 7 | ``` 8 | $ npm i 9 | ``` 10 | 11 | ### Development Mode 12 | 13 | ``` 14 | $ npm run dev 15 | ``` 16 | 17 | Now a valid AMP page - `http://localhost:3000/` is available 18 | 19 | ### Prouction Mode 20 | 21 | ``` 22 | $ npm run build 23 | ``` 24 | 25 | ``` 26 | $ npm start 27 | ``` 28 | -------------------------------------------------------------------------------- /examples/global-scoped-css/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-css-modules", 3 | "version": "1.0.0", 4 | "description": "This is a example of using amp-react-renderer-plugin in React + css-modules project", 5 | "main": "index.js", 6 | "author": "CR Jimmy ", 7 | "license": "MIT", 8 | "dependencies": { 9 | "express": "^4.16.3", 10 | "react": "^16.8.6", 11 | "react-dom": "^16.8.6" 12 | }, 13 | "devDependencies": { 14 | "@babel/cli": "^7.4.4", 15 | "@babel/core": "^7.4.5", 16 | "@babel/preset-env": "^7.4.5", 17 | "@babel/preset-react": "^7.0.0", 18 | "@babel/register": "^7.4.4", 19 | "babel-loader": "^8.x.x", 20 | "css-loader": "^2.x.x", 21 | "mini-css-extract-plugin": "^0.6.0", 22 | "nodemon": "^1.17.3", 23 | "webpack": "^4.30.0", 24 | "webpack-dev-middleware": "^3.6.2", 25 | "write-file-webpack-plugin": "^4.2.0" 26 | }, 27 | "scripts": { 28 | "start": "NODE_ENV=production node ./dist/server.js", 29 | "build": "BABEL_ENV=production ./node_modules/@babel/cli/bin/babel.js src/ --out-dir dist --copy-files && webpack", 30 | "dev": "nodemon --watch src --ignore src/AmpReactRenderer src/server-dev.js" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/global-scoped-css/src/components/Application.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Application = () => { 4 | return ( 5 |
6 | 9 |
10 |
11 | This is a blue box. 12 |
13 |
14 |
15 | This is a red box. 16 |
17 |
18 |
19 | This is a green box. 20 |
21 | 22 | 26 |
27 | ) 28 | } 29 | 30 | export default Application 31 | -------------------------------------------------------------------------------- /examples/global-scoped-css/src/server-dev.js: -------------------------------------------------------------------------------- 1 | require('@babel/register')({ 2 | babelrc: false, 3 | presets: ['@babel/react', '@babel/env'] 4 | }) 5 | 6 | const webpackConfig = require('../webpack.config.dev.js') 7 | const webpackDevMiddleware = require('webpack-dev-middleware') 8 | const webpack = require('webpack') 9 | const compiler = webpack(webpackConfig) 10 | const server = require('./server.js') 11 | 12 | // apply webpack dev middleware to enable Amp Html Renderer auto rebuilding 13 | server.use(webpackDevMiddleware(compiler)) 14 | 15 | server.listen(3000, () => console.log('Example app listening on port 3000!')) 16 | -------------------------------------------------------------------------------- /examples/global-scoped-css/src/server.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const express = require('express') 3 | const React = require('react') 4 | const Application = require('./components/Application.js').default 5 | 6 | const server = express() 7 | 8 | server.get('/', (req, res) => { 9 | const ampHtmlRenderer = require('../bundle/AmpHtmlRenderer.js') 10 | 11 | res.send( 12 | ampHtmlRenderer({ 13 | entryName: 'home', 14 | AppComponent: , 15 | title: 'This is my first AMP page powered by React + CSS modules', 16 | canonical: 'https://jimmy.amp.com', 17 | headComponents: null 18 | }) 19 | ) 20 | }) 21 | 22 | if (process.env.NODE_ENV === 'production') { 23 | server.listen(3000, () => console.log('Example app listening on port 3000!')) 24 | } else { 25 | module.exports = server 26 | } 27 | -------------------------------------------------------------------------------- /examples/global-scoped-css/src/styles/global.css: -------------------------------------------------------------------------------- 1 | .blue-box, .red-box, .green-box { 2 | width: 100%; 3 | height: 280px; 4 | } 5 | 6 | .blue-box { 7 | background: blue; 8 | } 9 | 10 | .red-box { 11 | background: red; 12 | } 13 | 14 | .green-box { 15 | background: green; 16 | } 17 | -------------------------------------------------------------------------------- /examples/global-scoped-css/webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') 3 | const WriteFilePlugin = require('write-file-webpack-plugin') 4 | const AmpReactRendererPlugin = require('../../index-compiled') 5 | 6 | module.exports = { 7 | mode: 'development', 8 | entry: { 9 | home: [ 10 | path.resolve(__dirname, './src/styles/global.css'), 11 | path.resolve(__dirname, './src/components/Application.js') 12 | ] 13 | }, 14 | output: { 15 | filename: '[name].js', 16 | path: path.resolve(__dirname, 'bundle') 17 | }, 18 | module: { 19 | rules: [ 20 | { 21 | test: /\.js$/, 22 | use: 'babel-loader' 23 | }, 24 | { 25 | test: /\.css$/, 26 | use: [ 27 | { 28 | loader: MiniCssExtractPlugin.loader 29 | }, 30 | { 31 | loader: 'css-loader' 32 | } 33 | ] 34 | } 35 | ] 36 | }, 37 | plugins: [ 38 | new MiniCssExtractPlugin({ 39 | // Options similar to the same options in webpackOptions.output 40 | // both options are optional 41 | filename: '[name].css', 42 | chunkFilename: '[id].css', 43 | }), 44 | new AmpReactRendererPlugin(), 45 | new WriteFilePlugin() 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /examples/global-scoped-css/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') 3 | const AmpReactRendererPlugin = require('../../index-compiled') 4 | 5 | module.exports = { 6 | mode: 'development', 7 | entry: { 8 | home: [ 9 | path.resolve(__dirname, './src/styles/global.css'), 10 | path.resolve(__dirname, './src/components/Application.js') 11 | ] 12 | }, 13 | output: { 14 | filename: '[name].js', 15 | path: path.resolve(__dirname, 'bundle') 16 | }, 17 | module: { 18 | rules: [ 19 | { 20 | test: /\.js$/, 21 | use: 'babel-loader' 22 | }, 23 | { 24 | test: /\.css$/, 25 | use: [ 26 | { 27 | loader: MiniCssExtractPlugin.loader 28 | }, 29 | { 30 | loader: 'css-loader' 31 | } 32 | ] 33 | } 34 | ] 35 | }, 36 | plugins: [ 37 | new MiniCssExtractPlugin({ 38 | // Options similar to the same options in webpackOptions.output 39 | // both options are optional 40 | filename: '[name].css', 41 | chunkFilename: '[id].css', 42 | }), 43 | new AmpReactRendererPlugin() 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /examples/multiple-pages/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/env", "@babel/react"] 3 | } -------------------------------------------------------------------------------- /examples/multiple-pages/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | bundle/ 4 | -------------------------------------------------------------------------------- /examples/multiple-pages/README.md: -------------------------------------------------------------------------------- 1 | # Example: Build multiple AMP pages with React + global scoped css 2 | 3 | ## Quick Start 4 | 5 | ### Dependencies Installation 6 | 7 | ``` 8 | $ npm i 9 | ``` 10 | 11 | ### Development Mode 12 | 13 | ``` 14 | $ npm run dev 15 | ``` 16 | 17 | Visit `http://localhost:3000/page1` and `http://localhost:3000/page2` to see how we handle mutiple pages application. 18 | 19 | ### Prouction Mode 20 | 21 | ``` 22 | $ npm run build 23 | ``` 24 | 25 | ``` 26 | $ npm start 27 | ``` 28 | -------------------------------------------------------------------------------- /examples/multiple-pages/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-css-modules", 3 | "version": "1.0.0", 4 | "description": "This is a example of using amp-react-renderer-plugin in React + css-modules project", 5 | "main": "index.js", 6 | "author": "CR Jimmy ", 7 | "license": "MIT", 8 | "dependencies": { 9 | "express": "^4.16.3", 10 | "react": "^16.8.6", 11 | "react-dom": "^16.8.6" 12 | }, 13 | "devDependencies": { 14 | "@babel/cli": "^7.4.4", 15 | "@babel/core": "^7.4.5", 16 | "@babel/preset-env": "^7.4.5", 17 | "@babel/preset-react": "^7.0.0", 18 | "@babel/register": "^7.4.4", 19 | "babel-loader": "^8.x.x", 20 | "css-loader": "^2.x.x", 21 | "mini-css-extract-plugin": "^0.6.0", 22 | "nodemon": "^1.17.3", 23 | "webpack": "^4.30.0", 24 | "webpack-dev-middleware": "^3.6.2", 25 | "write-file-webpack-plugin": "^4.2.0" 26 | }, 27 | "scripts": { 28 | "start": "NODE_ENV=production node ./dist/server.js", 29 | "build": "BABEL_ENV=production ./node_modules/@babel/cli/bin/babel.js src/ --out-dir dist --copy-files && webpack", 30 | "dev": "nodemon --watch src --ignore src/AmpReactRenderer src/server-dev.js" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/multiple-pages/src/components/Page1.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Page1 = () => { 4 | return ( 5 |
6 |

Hello! I am page#1

7 | 10 |
11 |
12 | This is a blue box. 13 |
14 |
15 |
16 | This is a red box. 17 |
18 |
19 |
20 | This is a green box. 21 |
22 | 23 |
24 | ) 25 | } 26 | 27 | export default Page1 28 | -------------------------------------------------------------------------------- /examples/multiple-pages/src/components/Page2.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Page2 = () => { 4 | return ( 5 |
6 |

Hello! I am page#2

7 | 11 |
12 | ) 13 | } 14 | 15 | export default Page2 16 | -------------------------------------------------------------------------------- /examples/multiple-pages/src/server-dev.js: -------------------------------------------------------------------------------- 1 | require('@babel/register')({ 2 | babelrc: false, 3 | presets: ["@babel/env", "@babel/react"] 4 | }) 5 | 6 | const webpackConfig = require('../webpack.config.dev.js') 7 | const webpackDevMiddleware = require('webpack-dev-middleware') 8 | const webpack = require('webpack') 9 | const compiler = webpack(webpackConfig) 10 | const server = require('./server.js') 11 | 12 | // apply webpack dev middleware to enable Amp Html Renderer auto rebuilding 13 | server.use(webpackDevMiddleware(compiler)) 14 | 15 | server.listen(3000, () => console.log('Example app listening on port 3000!')) 16 | -------------------------------------------------------------------------------- /examples/multiple-pages/src/server.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const express = require('express') 3 | const React = require('react') 4 | const Page1 = require('./components/Page1.js').default 5 | const Page2 = require('./components/Page2.js').default 6 | 7 | const server = express() 8 | 9 | server.get('/page1', (req, res) => { 10 | const ampHtmlRenderer = require('../bundle/AmpHtmlRenderer.js') 11 | 12 | res.send( 13 | ampHtmlRenderer({ 14 | entryName: 'page1', 15 | AppComponent: , 16 | title: 'This is AMP page#1', 17 | canonical: 'https://jimmy.amp.com', 18 | headComponents: null 19 | }) 20 | ) 21 | }) 22 | 23 | server.get('/page2', (req, res) => { 24 | const ampHtmlRenderer = require('../bundle/AmpHtmlRenderer.js') 25 | 26 | res.send( 27 | ampHtmlRenderer({ 28 | entryName: 'page2', 29 | AppComponent: , 30 | title: 'This is AMP page#2', 31 | canonical: 'https://jimmy.amp.com', 32 | headComponents: null 33 | }) 34 | ) 35 | }) 36 | 37 | if (process.env.NODE_ENV === 'production') { 38 | server.listen(3000, () => console.log('Example app listening on port 3000!')) 39 | } else { 40 | module.exports = server 41 | } 42 | -------------------------------------------------------------------------------- /examples/multiple-pages/src/styles/global.css: -------------------------------------------------------------------------------- 1 | .blue-box, .red-box, .green-box { 2 | width: 100%; 3 | height: 280px; 4 | } 5 | 6 | .blue-box { 7 | background: blue; 8 | } 9 | 10 | .red-box { 11 | background: red; 12 | } 13 | 14 | .green-box { 15 | background: green; 16 | } 17 | -------------------------------------------------------------------------------- /examples/multiple-pages/webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') 3 | const WriteFilePlugin = require('write-file-webpack-plugin') 4 | const AmpReactRendererPlugin = require('../../index-compiled') 5 | 6 | module.exports = { 7 | mode: 'development', 8 | entry: { 9 | page1: [ 10 | path.resolve(__dirname, './src/styles/global.css'), 11 | path.resolve(__dirname, './src/components/Page1.js') 12 | ], 13 | page2: [ 14 | path.resolve(__dirname, './src/styles/global.css'), 15 | path.resolve(__dirname, './src/components/Page2.js') 16 | ] 17 | }, 18 | output: { 19 | filename: '[name].js', 20 | path: path.resolve(__dirname, 'bundle') 21 | }, 22 | module: { 23 | rules: [ 24 | { 25 | test: /\.js$/, 26 | use: 'babel-loader' 27 | }, 28 | { 29 | test: /\.css$/, 30 | use: [ 31 | { 32 | loader: MiniCssExtractPlugin.loader 33 | }, 34 | { 35 | loader: 'css-loader' 36 | } 37 | ] 38 | } 39 | ] 40 | }, 41 | plugins: [ 42 | new MiniCssExtractPlugin({ 43 | // Options similar to the same options in webpackOptions.output 44 | // both options are optional 45 | filename: '[name].css', 46 | chunkFilename: '[id].css', 47 | }), 48 | new AmpReactRendererPlugin(), 49 | new WriteFilePlugin() 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /examples/multiple-pages/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') 3 | const AmpReactRendererPlugin = require('../../index-compiled') 4 | 5 | module.exports = { 6 | mode: 'development', 7 | entry: { 8 | page1: [ 9 | path.resolve(__dirname, './src/styles/global.css'), 10 | path.resolve(__dirname, './src/components/Page1.js') 11 | ], 12 | page2: [ 13 | path.resolve(__dirname, './src/styles/global.css'), 14 | path.resolve(__dirname, './src/components/Page2.js') 15 | ] 16 | }, 17 | output: { 18 | filename: '[name].js', 19 | path: path.resolve(__dirname, 'bundle') 20 | }, 21 | module: { 22 | rules: [ 23 | { 24 | test: /\.js$/, 25 | use: 'babel-loader' 26 | }, 27 | { 28 | test: /\.css$/, 29 | use: [ 30 | { 31 | loader: MiniCssExtractPlugin.loader 32 | }, 33 | { 34 | loader: 'css-loader' 35 | } 36 | ] 37 | } 38 | ] 39 | }, 40 | plugins: [ 41 | new MiniCssExtractPlugin({ 42 | // Options similar to the same options in webpackOptions.output 43 | // both options are optional 44 | filename: '[name].css', 45 | chunkFilename: '[id].css', 46 | }), 47 | new AmpReactRendererPlugin() 48 | ] 49 | } 50 | -------------------------------------------------------------------------------- /examples/redux/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/env", "@babel/react"], 3 | "env": { 4 | "production": { 5 | "presets": ["@babel/env", "@babel/react"], 6 | "plugins": [ 7 | [ 8 | "css-modules-transform", { 9 | "generateScopedName": "[name]__[local]___[hash:base64:5]", 10 | "extensions": [".css"] 11 | } 12 | ] 13 | ] 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /examples/redux/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | bundle/ 4 | -------------------------------------------------------------------------------- /examples/redux/README.md: -------------------------------------------------------------------------------- 1 | # Example: Build AMP page with React + Redux + CSS modules 2 | 3 | ## Quick Start 4 | 5 | ### Dependencies Installation 6 | 7 | ``` 8 | $ npm i 9 | ``` 10 | 11 | ### Development Mode 12 | 13 | ``` 14 | $ npm run dev 15 | ``` 16 | 17 | Now a valid AMP page - `http://localhost:3000/` is available 18 | 19 | ### Prouction Mode 20 | 21 | ``` 22 | $ npm run build 23 | ``` 24 | 25 | ``` 26 | $ npm start 27 | ``` 28 | -------------------------------------------------------------------------------- /examples/redux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-css-modules", 3 | "version": "1.0.0", 4 | "description": "This is a example of using amp-react-renderer-plugin in React + css-modules project", 5 | "main": "index.js", 6 | "author": "CR Jimmy ", 7 | "license": "MIT", 8 | "dependencies": { 9 | "express": "^4.16.3", 10 | "react": "^16.8.6", 11 | "react-dom": "^16.8.6", 12 | "react-redux": "^5.0.7", 13 | "redux": "^4.0.0" 14 | }, 15 | "devDependencies": { 16 | "@babel/cli": "^7.4.4", 17 | "@babel/core": "^7.4.5", 18 | "@babel/preset-env": "^7.4.5", 19 | "@babel/preset-react": "^7.0.0", 20 | "@babel/register": "^7.4.4", 21 | "babel-loader": "8.0.0", 22 | "babel-plugin-css-modules-transform": "^1.5.0", 23 | "css-loader": "^2.x.x", 24 | "mini-css-extract-plugin": "^0.6.0", 25 | "nodemon": "^1.17.3", 26 | "webpack": "^4.30.0", 27 | "webpack-dev-middleware": "^3.6.2", 28 | "write-file-webpack-plugin": "^4.2.0" 29 | }, 30 | "scripts": { 31 | "start": "NODE_ENV=production node ./dist/server.js", 32 | "build": "BABEL_ENV=production ./node_modules/@babel/cli/bin/babel.js src/ --out-dir dist --copy-files && webpack --display-modules", 33 | "dev": "nodemon --watch src --ignore src/AmpReactRenderer src/server-dev.js" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /examples/redux/src/components/Application.css: -------------------------------------------------------------------------------- 1 | .blue-box, .red-box, .green-box { 2 | width: 100%; 3 | height: 280px; 4 | } 5 | 6 | .blue-box { 7 | background: blue; 8 | } 9 | 10 | .red-box { 11 | background: red; 12 | } 13 | 14 | .green-box { 15 | background: green; 16 | } 17 | -------------------------------------------------------------------------------- /examples/redux/src/components/Application.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import style from './Application.css' 3 | 4 | const Application = ({ slides = [] }) => { 5 | return ( 6 |
7 |

Create AMP app, the React way

8 | 11 | { 12 | slides.map((slide, index) => { 13 | const { color, des } = slide 14 | return ( 15 |
16 |
17 | {des} 18 |
19 | ) 20 | }) 21 | } 22 | 23 | 27 |
28 | ) 29 | } 30 | 31 | export default Application 32 | -------------------------------------------------------------------------------- /examples/redux/src/components/Root.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { createStore } from 'redux' 3 | import { Provider } from 'react-redux' 4 | import AppContainer from '../containers/Application.js' 5 | 6 | const initState = { 7 | slides: [ 8 | { 9 | color: 'blue', 10 | des: 'This is a blue box.' 11 | }, 12 | { 13 | color: 'red', 14 | des: 'This is a red box.' 15 | }, 16 | { 17 | color: 'green', 18 | des: 'This is a green box.' 19 | } 20 | ] 21 | } 22 | 23 | const reducer = function (state = initState, action) { 24 | return initState 25 | } 26 | 27 | const store = createStore(reducer) 28 | 29 | const Root = () => { 30 | return ( 31 | 32 | 33 | 34 | ) 35 | } 36 | 37 | export default Root 38 | -------------------------------------------------------------------------------- /examples/redux/src/containers/Application.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import Application from '../components/Application.js' 3 | 4 | const mapStateToProps = (state) => { 5 | const { slides } = state 6 | 7 | return { 8 | slides 9 | } 10 | } 11 | 12 | export default connect(mapStateToProps)(Application) 13 | -------------------------------------------------------------------------------- /examples/redux/src/server-dev.js: -------------------------------------------------------------------------------- 1 | require('@babel/register')({ 2 | babelrc: false, 3 | presets: ["@babel/env", "@babel/react"], 4 | plugins: [[ 5 | 'css-modules-transform', { 6 | 'generateScopedName': '[name]__[local]___[hash:base64:5]', 7 | 'extensions': ['.css'] 8 | } 9 | ]] 10 | }) 11 | 12 | const webpackConfig = require('../webpack.config.dev.js') 13 | const webpackDevMiddleware = require('webpack-dev-middleware') 14 | const webpack = require('webpack') 15 | const compiler = webpack(webpackConfig) 16 | const server = require('./server.js') 17 | 18 | // apply webpack dev middleware to enable Amp Html Renderer auto rebuilding 19 | server.use(webpackDevMiddleware(compiler)) 20 | 21 | server.listen(3000, () => console.log('Example app listening on port 3000!')) 22 | -------------------------------------------------------------------------------- /examples/redux/src/server.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const express = require('express') 3 | const React = require('react') 4 | const Application = require('./components/Root.js').default 5 | 6 | const server = express() 7 | 8 | server.get('/', (req, res) => { 9 | const ampHtmlRenderer = require('../bundle/AmpHtmlRenderer.js') 10 | 11 | res.send( 12 | ampHtmlRenderer({ 13 | entryName: 'home', 14 | AppComponent: , 15 | title: 'This is my first AMP page powered by React + CSS modules', 16 | canonical: 'https://jimmy.amp.com', 17 | headComponents: null 18 | }) 19 | ) 20 | }) 21 | 22 | if (process.env.NODE_ENV === 'production') { 23 | server.listen(3000, () => console.log('Example app listening on port 3000!')) 24 | } else { 25 | module.exports = server 26 | } 27 | -------------------------------------------------------------------------------- /examples/redux/webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') 3 | const WriteFilePlugin = require('write-file-webpack-plugin') 4 | const AmpReactRendererPlugin = require('../../index-compiled') 5 | 6 | module.exports = { 7 | mode: 'development', 8 | entry: { 9 | home: path.resolve(__dirname, './src/components/Root.js') 10 | }, 11 | output: { 12 | filename: '[name].js', 13 | path: path.resolve(__dirname, 'bundle') 14 | }, 15 | module: { 16 | rules: [ 17 | { 18 | test: /\.js$/, 19 | use: 'babel-loader' 20 | }, 21 | { 22 | test: /\.css$/, 23 | use: [ 24 | { 25 | loader: MiniCssExtractPlugin.loader 26 | }, 27 | { 28 | loader: 'css-loader', 29 | query: { 30 | modules: true, 31 | localIdentName: '[name]__[local]___[hash:base64:5]' 32 | } 33 | } 34 | ] 35 | } 36 | ] 37 | }, 38 | plugins: [ 39 | new MiniCssExtractPlugin({ 40 | // Options similar to the same options in webpackOptions.output 41 | // both options are optional 42 | filename: '[name].css', 43 | chunkFilename: '[id].css', 44 | }), 45 | new AmpReactRendererPlugin(), 46 | new WriteFilePlugin() 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /examples/redux/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') 3 | const AmpReactRendererPlugin = require('../../index-compiled') 4 | 5 | module.exports = { 6 | mode: 'development', 7 | entry: { 8 | home: path.resolve(__dirname, './src/components/Root') 9 | }, 10 | output: { 11 | filename: '[name].js', 12 | path: path.resolve(__dirname, 'bundle') 13 | }, 14 | module: { 15 | rules: [ 16 | { 17 | test: /\.js$/, 18 | use: 'babel-loader' 19 | }, 20 | { 21 | test: /\.css$/, 22 | use: [ 23 | { 24 | loader: MiniCssExtractPlugin.loader 25 | }, 26 | { 27 | loader: 'css-loader', 28 | query: { 29 | modules: true, 30 | localIdentName: '[name]__[local]___[hash:base64:5]' 31 | } 32 | } 33 | ] 34 | } 35 | ] 36 | }, 37 | plugins: [ 38 | new MiniCssExtractPlugin({ 39 | // Options similar to the same options in webpackOptions.output 40 | // both options are optional 41 | filename: '[name].css', 42 | chunkFilename: '[id].css', 43 | }), 44 | new AmpReactRendererPlugin() 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /examples/styled-components/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/env", "@babel/react"], 3 | "plugins": [ 4 | ["babel-plugin-styled-components", { 5 | "ssr": true 6 | }] 7 | ] 8 | } -------------------------------------------------------------------------------- /examples/styled-components/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | bundle/ 4 | -------------------------------------------------------------------------------- /examples/styled-components/README.md: -------------------------------------------------------------------------------- 1 | # Example: Build AMP page with React + Styled Components 2 | 3 | ## Quick Start 4 | 5 | ### Dependencies Installation 6 | 7 | ``` 8 | $ npm i 9 | ``` 10 | 11 | ### Development Mode 12 | 13 | ``` 14 | $ npm run dev 15 | ``` 16 | 17 | Now a valid AMP page - `http://localhost:3000/` is available 18 | 19 | ### Prouction Mode 20 | 21 | ``` 22 | $ npm run build 23 | ``` 24 | 25 | ``` 26 | $ npm start 27 | ``` 28 | -------------------------------------------------------------------------------- /examples/styled-components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-css-modules", 3 | "version": "1.0.0", 4 | "description": "This is a example of using amp-react-renderer-plugin in React + css-modules project", 5 | "main": "index.js", 6 | "author": "CR Jimmy ", 7 | "license": "MIT", 8 | "dependencies": { 9 | "express": "^4.16.3", 10 | "react": "^16.8.6", 11 | "react-dom": "^16.8.6", 12 | "styled-components": "^3.2.6" 13 | }, 14 | "devDependencies": { 15 | "@babel/cli": "^7.4.4", 16 | "@babel/core": "^7.4.5", 17 | "@babel/preset-env": "^7.4.5", 18 | "@babel/preset-react": "^7.0.0", 19 | "@babel/register": "^7.4.4", 20 | "babel-loader": "^8.x.x", 21 | "babel-plugin-styled-components": "^1.10.0", 22 | "nodemon": "^1.17.3", 23 | "webpack": "^4.30.0", 24 | "webpack-dev-middleware": "^3.6.2", 25 | "write-file-webpack-plugin": "^4.2.0" 26 | }, 27 | "scripts": { 28 | "start": "NODE_ENV=production node ./dist/server.js", 29 | "build": "BABEL_ENV=production ./node_modules/@babel/cli/bin/babel.js src/ --out-dir dist --copy-files && webpack", 30 | "dev": "nodemon --watch src --ignore src/AmpReactRenderer src/server-dev.js" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/styled-components/src/components/Application.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | 4 | const Slide = styled.div` 5 | width: 100%; 6 | height: 280px; 7 | ` 8 | 9 | const BlueSlide = styled(Slide)` 10 | background-color: blue; 11 | ` 12 | 13 | const RedSlide = styled(Slide)` 14 | background-color: red; 15 | ` 16 | 17 | const GreenSlide = styled(Slide)` 18 | background-color: green; 19 | ` 20 | 21 | const Application = () => { 22 | return ( 23 |
24 | 27 |
28 | 29 | 💅This is a blue box. 30 |
31 |
32 | 33 | 💅This is a red box. 34 |
35 |
36 | 37 | 💅This is a green box. 38 |
39 |
40 | 44 |
45 | ) 46 | } 47 | 48 | export default Application 49 | -------------------------------------------------------------------------------- /examples/styled-components/src/server-dev.js: -------------------------------------------------------------------------------- 1 | require('@babel/register')({ 2 | babelrc: false, 3 | presets: ["@babel/env", "@babel/react"] 4 | }) 5 | 6 | const path = require('path') 7 | const webpackConfig = require('../webpack.config.dev.js') 8 | const webpackDevMiddleware = require('webpack-dev-middleware') 9 | const webpack = require('webpack') 10 | const compiler = webpack(webpackConfig) 11 | const server = require('./server.js') 12 | 13 | // apply webpack dev middleware to enable Amp Html Renderer auto rebuilding 14 | server.use(webpackDevMiddleware(compiler)) 15 | 16 | server.listen(3000, () => console.log('Example app listening on port 3000!')) 17 | -------------------------------------------------------------------------------- /examples/styled-components/src/server.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const express = require('express') 3 | const React = require('react') 4 | const { renderToString } = require('react-dom/server') 5 | const Application = require('./components/Application.js').default 6 | const { ServerStyleSheet } = require('styled-components') 7 | 8 | const server = express() 9 | 10 | server.get('/', (req, res) => { 11 | const sheet = new ServerStyleSheet() 12 | const html = renderToString(sheet.collectStyles()) 13 | const runtimeCss = sheet.getStyleElement()[0].props.dangerouslySetInnerHTML.__html 14 | const ampHtmlRenderer = require('../bundle/AmpHtmlRenderer.js') 15 | 16 | res.send( 17 | ampHtmlRenderer({ 18 | entryName: 'home', 19 | AppComponent: , 20 | title: 'This is my first AMP page powered by React + styled-components', 21 | canonical: 'https://jimmy.amp.com', 22 | headComponents: null, 23 | runtimeCss 24 | }) 25 | ) 26 | }) 27 | 28 | if (process.env.NODE_ENV === 'production') { 29 | server.listen(3000, () => console.log('Example app listening on port 3000!')) 30 | } else { 31 | module.exports = server 32 | } 33 | -------------------------------------------------------------------------------- /examples/styled-components/src/styles/global.css: -------------------------------------------------------------------------------- 1 | .blue-box, .red-box, .green-box { 2 | width: 100%; 3 | height: 280px; 4 | } 5 | 6 | .blue-box { 7 | background: blue; 8 | } 9 | 10 | .red-box { 11 | background: red; 12 | } 13 | 14 | .green-box { 15 | background: green; 16 | } 17 | -------------------------------------------------------------------------------- /examples/styled-components/webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const WriteFilePlugin = require('write-file-webpack-plugin') 3 | const AmpReactRendererPlugin = require('../../index-compiled') 4 | 5 | module.exports = { 6 | mode: 'development', 7 | entry: { 8 | home: path.resolve(__dirname, './src/components/Application.js') 9 | }, 10 | output: { 11 | filename: '[name].js', 12 | path: path.resolve(__dirname, 'bundle') 13 | }, 14 | module: { 15 | rules: [ 16 | { 17 | test: /\.js$/, 18 | use: 'babel-loader' 19 | } 20 | ] 21 | }, 22 | plugins: [ 23 | new AmpReactRendererPlugin(), 24 | new WriteFilePlugin() 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /examples/styled-components/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const AmpReactRendererPlugin = require('../../index-compiled') 3 | 4 | module.exports = { 5 | mode: 'development', 6 | entry: { 7 | home: [ 8 | path.resolve(__dirname, './src/components/Application.js') 9 | ] 10 | }, 11 | output: { 12 | filename: '[name].js', 13 | path: path.resolve(__dirname, 'bundle') 14 | }, 15 | module: { 16 | rules: [ 17 | { 18 | test: /\.js$/, 19 | use: 'babel-loader' 20 | } 21 | ] 22 | }, 23 | plugins: [ 24 | new AmpReactRendererPlugin() 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /lib/HtmlComponentBuilder.js: -------------------------------------------------------------------------------- 1 | const transpiler = require('@babel/core') 2 | const constants = require('../conf/constants.json') 3 | 4 | class HtmlComponentBuilder { 5 | build (extComponentScripts) { 6 | const raw = ` 7 | const React = require('react') 8 | 9 | module.exports = function (props) { 10 | const { AppComponent, title, canonical, headComponents } = props 11 | 12 | return ( 13 | 14 | 15 | 16 | 17 | 18 | 19 | {title} 20 | 21 | {headComponents} 22 | #react-amp-inline-style# 23 | 24 | ${extComponentScripts === null ? '' : extComponentScripts} 25 | 26 | 27 | {AppComponent} 28 | 29 | 30 | ) 31 | } 32 | ` 33 | 34 | return transpiler.transform(raw, { presets: ['@babel/react'] }).code 35 | } 36 | } 37 | 38 | module.exports = HtmlComponentBuilder 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "amp-react-renderer-plugin", 3 | "version": "0.1.7", 4 | "description": ":zap:Plugin make it painless to create React component based AMP page:zap:", 5 | "main": "./index-compiled.js", 6 | "repository": "git@github.com:jimmy319/amp-react-renderer-plugin.git", 7 | "author": "CR Jimmy ", 8 | "license": "MIT", 9 | "devDependencies": { 10 | "@babel/cli": "^7.15.7", 11 | "@babel/core": "^7.15.8", 12 | "@babel/preset-env": "^7.15.8", 13 | "@babel/preset-react": "^7.14.5", 14 | "amphtml-validator": "^1.0.35", 15 | "babel-loader": "^8.2.2", 16 | "babel-plugin-css-modules-transform": "^1.6.2", 17 | "css-loader": "^2.0.0", 18 | "jest": "^27.2.5", 19 | "mini-css-extract-plugin": "^1.3.3", 20 | "react": "^16.8.6", 21 | "react-ampify": "^0.0.1", 22 | "react-dom": "^16.8.6", 23 | "standard": "^16.0.4", 24 | "webpack": "^5.12.2", 25 | "webpack-cli": "4.3.1" 26 | }, 27 | "peerDependencies": { 28 | "react": "^16.2.0", 29 | "react-dom": "^16.2.0", 30 | "webpack": "4.x.x || 5.x.x" 31 | }, 32 | "keywords": [ 33 | "amp", 34 | "amp-html", 35 | "react", 36 | "webpack", 37 | "webpack-plugin", 38 | "plugin" 39 | ], 40 | "scripts": { 41 | "build": "babel index.js --out-file index-compiled.js", 42 | "test": "webpack --config webpack.test.config.js && jest && codecov", 43 | "test:watch": "jest --watch", 44 | "precommit": "lint-staged" 45 | }, 46 | "jest": { 47 | "coverageDirectory": "./coverage/", 48 | "collectCoverage": true 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-3q-player/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 10 | 11 | ) 12 | } 13 | 14 | module.exports = Application 15 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-3q-player/render-amp-3q-player.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-3q-player component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-3q-player' 10 | const canonical = 'https://amp-3q-player.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-3q-player', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-access-laterpay/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 |
7 |
8 |
9 | 10 |
11 | Oops... Something broke. 12 |
13 | 14 |
15 |

...article content...

16 |
17 |
18 | ) 19 | } 20 | 21 | module.exports = Application 22 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-access-laterpay/render-amp-access-laterpay.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-access-laterpay component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-access-laterpay' 10 | const canonical = 'https://amp-access-laterpay.test.com.tw' 11 | const json = { 12 | 'vendor': 'laterpay', 13 | 'laterpay': { 14 | 'articleTitleSelector': '.preview > h3', 15 | 'sandbox': true 16 | } 17 | } 18 | const headComponents = ["`; 4 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-auto-ads/render-amp-auto-ads.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-auto-ads component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-auto-ads' 10 | const canonical = 'https://amp-auto-ads.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-auto-ads', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-beopinion/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 11 | 12 | ) 13 | } 14 | 15 | module.exports = Application 16 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-beopinion/render-amp-beopinion.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-beopinion component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-beopinion' 10 | const canonical = 'https://amp-beopinion.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-beopinion', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-bind/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const { createJsonScriptElement } = require('react-ampify') 3 | 4 | const Application = () => { 5 | const json = { 6 | 'currentAnimal': 'dog', 7 | 'dog': { 8 | 'imageUrl': '/img/Border_Collie.jpg', 9 | 'videoUrl': '/video/dog-video.mp4', 10 | 'style': 'greenBackground', 11 | 'iframeUrl': 'https://player.vimeo.com/video/183849543' 12 | }, 13 | 'cat': { 14 | 'imageUrl': '/img/cat-looking-up-300x200.jpg', 15 | 'videoUrl': '/video/cat-video.mp4', 16 | 'style': 'redBackground', 17 | 'iframeUrl': 'https://player.vimeo.com/video/185199565' 18 | } 19 | } 20 | return ( 21 | 22 | 23 | {createJsonScriptElement(json)} 24 | 25 | 26 | ) 27 | } 28 | 29 | module.exports = Application 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-bind/render-amp-state.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-state component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-bind' 10 | const canonical = 'https://amp-bind.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-bind', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-bodymovin-animation/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 10 | 11 | ) 12 | } 13 | 14 | module.exports = Application 15 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-bodymovin-animation/render-amp-bodymovin-animation.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-bodymovin-animation component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-bodymovin-animation' 10 | const canonical = 'https://amp-bodymovin-animation.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-bodymovin-animation', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-brid-player/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 12 | 13 | ) 14 | } 15 | 16 | module.exports = Application 17 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-brid-player/render-amp-brid-player.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-brid-player component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-brid-player' 10 | const canonical = 'https://amp-brid-player.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-brid-player', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-brightcove/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 13 | 14 | ) 15 | } 16 | 17 | module.exports = Application 18 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-brightcove/render-amp-brightcove.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-brightcove component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-brightcove' 10 | const canonical = 'https://amp-brightcove.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-brightcove', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-byside-content/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 14 | 15 | ) 16 | } 17 | 18 | module.exports = Application 19 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-byside-content/render-amp-byside-content.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-byside-content component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-byside-content' 10 | const canonical = 'https://amp-byside-content.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-byside-content', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-call-tracking/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 7 | +1 (23) 456-789 8 | 9 | 10 | ) 11 | } 12 | 13 | module.exports = Application 14 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-call-tracking/render-amp-call-tracking.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-call-tracking component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-call-tracking' 10 | const canonical = 'https://amp-call-tracking.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-call-tracking', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-carousel/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 9 | 13 | 17 | 21 | 22 | 23 | ) 24 | } 25 | 26 | module.exports = Application 27 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-carousel/render-amp-carousel.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-carousel component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-carousel' 10 | const canonical = 'https://amp-carousel.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-carousel', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-consent/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const { createJsonScriptElement } = require('react-ampify') 3 | 4 | const Application = () => { 5 | const json = { 6 | 'consents': { 7 | 'my-consent': { 8 | 'checkConsentHref': 'https://foo.com/api/show-consent', 9 | 'promptUI': 'consent-ui' 10 | } 11 | } 12 | } 13 | return ( 14 | 15 | 16 | {createJsonScriptElement(json)} 17 | 22 | 23 | 24 | ) 25 | } 26 | 27 | module.exports = Application 28 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-consent/render-amp-consent.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-consent component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-consent' 10 | const canonical = 'https://amp-consent.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-consent', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-dailymotion/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 10 | 11 | ) 12 | } 13 | 14 | module.exports = Application 15 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-dailymotion/render-amp-dailymotion.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-dailymotion component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-dailymotion' 10 | const canonical = 'https://amp-dailymotion.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-dailymotion', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-date-picker/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 |
10 | 15 | 16 | 17 | 18 |
19 |
20 | ) 21 | } 22 | 23 | module.exports = Application 24 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-date-picker/render-amp-date-picker.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-date-picker component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-date-picker' 10 | const canonical = 'https://amp-date-picker.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-date-picker', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-experiment/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const { createJsonScriptElement } = require('react-ampify') 3 | 4 | const Application = () => { 5 | const json = { 6 | 'button-color-experiment': { 7 | 'variants': { 8 | '0': 30, 9 | '1': 30, 10 | '2': 30 11 | } 12 | } 13 | } 14 | return ( 15 | 16 | 17 | {createJsonScriptElement(json)} 18 | 19 | 20 | ) 21 | } 22 | 23 | module.exports = Application 24 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-experiment/render-amp-experiment.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-experiment component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-experiment' 10 | const canonical = 'https://amp-experiment.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-experiment', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-facebook-comments/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 10 | 11 | ) 12 | } 13 | 14 | module.exports = Application 15 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-facebook-comments/render-amp-facebook-comments.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-facebook-comments component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-facebook-comments' 10 | const canonical = 'https://amp-facebook-comments.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-facebook-comments', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-facebook-like/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 10 | 11 | ) 12 | } 13 | 14 | module.exports = Application 15 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-facebook-like/render-amp-facebook-like.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-facebook-like component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-facebook-like' 10 | const canonical = 'https://amp-facebook-like.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-facebook-like', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-facebook-page/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 10 | 11 | ) 12 | } 13 | 14 | module.exports = Application 15 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-facebook-page/render-amp-facebook-page.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-facebook-page component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-facebook-page' 10 | const canonical = 'https://amp-facebook-page.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-facebook-page', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-facebook/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 9 | 10 | ) 11 | } 12 | 13 | module.exports = Application 14 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-facebook/render-amp-facebook.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-facebook component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-facebook' 10 | const canonical = 'https://amp-facebook.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-facebook', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-fit-text/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 |
7 | 10 | Lorem ipsum dolor sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt. 11 | 12 |
13 |
14 | ) 15 | } 16 | 17 | module.exports = Application 18 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-fit-text/render-amp-fit-text.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-fit-text component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-fit-text' 10 | const canonical = 'https://amp-fit-text.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-fit-text', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-font/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 12 | 18 | 19 | ) 20 | } 21 | 22 | module.exports = Application 23 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-font/render-amp-font.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-font component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-font' 10 | const canonical = 'https://amp-font.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-font', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-form/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 |
12 |

Form Submission with Page Reload

13 |
14 | 19 |
20 | 25 |
26 |
27 | ) 28 | } 29 | 30 | module.exports = Application 31 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-form/render-amp-form.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-form component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-form' 10 | const canonical = 'https://amp-form.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-form', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-fx-collection/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 |

7 | A title that moves faster than other content. 8 |

9 |
10 | ) 11 | } 12 | 13 | module.exports = Application 14 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-fx-collection/render-amp-fx-collection.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-fx-collection component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-fx-collection' 10 | const canonical = 'https://amp-fx-collection.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-fx-collection', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-fx-flying-carpet/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 |
Advertising
7 | 8 |
my ad
9 |
10 |
Advertising
11 |
12 | ) 13 | } 14 | 15 | module.exports = Application 16 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-fx-flying-carpet/render-amp-fx-flying-carpet.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-fx-flying-carpet component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-fx-flying-carpet' 10 | const canonical = 'https://amp-fx-flying-carpet.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-fx-flying-carpet', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-geo/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const { createJsonScriptElement } = require('react-ampify') 3 | 4 | const Application = () => { 5 | const json = { 6 | 'ISOCountryGroups': { 7 | 'soccer': [ 'au', 'ca', 'ie', 'nz', 'us', 'za' ], 8 | 'football': [ 'unknown' ] 9 | } 10 | } 11 | return ( 12 | 13 | 14 | {createJsonScriptElement(json)} 15 | 16 | 17 | ) 18 | } 19 | 20 | module.exports = Application 21 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-geo/render-amp-geo.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-geo component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-geo' 10 | const canonical = 'https://amp-geo.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-geo', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-gfycat/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 11 | 12 | ) 13 | } 14 | 15 | module.exports = Application 16 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-gfycat/__snapshots__/render-amp-gfycat.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`render a valid AMP page with amp-gfycat component 1`] = `"case - amp-gfycat"`; 4 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-gfycat/render-amp-gfycat.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-gfycat component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-gfycat' 10 | const canonical = 'https://amp-gfycat.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-gfycat', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-gist/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 9 | 10 | ) 11 | } 12 | 13 | module.exports = Application 14 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-gist/__snapshots__/render-amp-gist.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`render a valid AMP page with amp-form component 1`] = `"case - amp-gist"`; 4 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-gist/render-amp-gist.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-form component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-gist' 10 | const canonical = 'https://amp-gist.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-gist', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-hulu/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 8 | 9 | ) 10 | } 11 | 12 | module.exports = Application 13 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-hulu/__snapshots__/render-amp-hulu.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`render a valid AMP page with amp-hulu component 1`] = `"case - amp-hulu"`; 4 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-hulu/render-amp-hulu.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-hulu component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-hulu' 10 | const canonical = 'https://amp-hulu.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-hulu', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-iframe/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 14 | 15 | ) 16 | } 17 | 18 | module.exports = Application 19 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-iframe/render-amp-iframe.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-iframe component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-iframe' 10 | const canonical = 'https://amp-iframe.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-iframe', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-ima-video/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 12 | 14 | 15 | 16 | ) 17 | } 18 | 19 | module.exports = Application 20 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-ima-video/render-amp-ima-video.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-ima-video component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-ima-video' 10 | const canonical = 'https://amp-ima-video.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-ima-video', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-image-lightbox/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 7 | 13 | 14 | 20 | 21 | ) 22 | } 23 | 24 | module.exports = Application 25 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-image-lightbox/render-amp-image-lightbox.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-image-lightbox component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-image-lightbox' 10 | const canonical = 'https://amp-image-lightbox.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-image-lightbox', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-imgur/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 10 | 11 | ) 12 | } 13 | 14 | module.exports = Application 15 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-imgur/__snapshots__/render-amp-imgur.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`render a valid AMP page with amp-imgur component 1`] = `"case - amp-imgur"`; 4 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-imgur/render-amp-imgur.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-imgur component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-imgur' 10 | const canonical = 'https://amp-imgur.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-imgur', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-instagram/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 12 | 13 | ) 14 | } 15 | 16 | module.exports = Application 17 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-instagram/render-amp-instagram.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-instagram component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-instagram' 10 | const canonical = 'https://amp-instagram.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-instagram', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-install-serviceworker/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 9 | 10 | ) 11 | } 12 | 13 | module.exports = Application 14 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-install-serviceworker/render-amp-install-serviceworker.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-install-serviceworker component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-install-serviceworker' 10 | const canonical = 'https://amp-install-serviceworker.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-install-serviceworker', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-izlesene/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 10 | 11 | ) 12 | } 13 | 14 | module.exports = Application 15 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-izlesene/__snapshots__/render-amp-izlesene.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`render a valid AMP page with amp-izlesene component 1`] = `"case - amp-izlesene"`; 4 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-izlesene/render-amp-izlesene.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-izlesene component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-izlesene' 10 | const canonical = 'https://amp-izlesene.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-izlesene', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-jwplayer/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 11 | 12 | ) 13 | } 14 | 15 | module.exports = Application 16 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-jwplayer/render-amp-jwplayer.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-jwplayer component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-jwplayer' 10 | const canonical = 'https://amp-jwplayer.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-jwplayer', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-kaltura-player/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 12 | 13 | ) 14 | } 15 | 16 | module.exports = Application 17 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-kaltura-player/render-amp-kaltura-player.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-kaltura-player component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-kaltura-player' 10 | const canonical = 'https://amp-kaltura-player.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-kaltura-player', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-lightbox-gallery/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 |
7 | 13 |
14 | Toronto's CN tower was built in 1976 and was the tallest free-standing structure until 2007. 15 |
16 |
17 |
18 | ) 19 | } 20 | 21 | module.exports = Application 22 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-lightbox-gallery/render-amp-lightbox-gallery.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-lightbox-gallery component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-lightbox-gallery' 10 | const canonical = 'https://amp-lightbox-gallery.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-lightbox-gallery', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-lightbox/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 8 |
12 |

Hello World!

13 |
14 |
15 |
16 | ) 17 | } 18 | 19 | module.exports = Application 20 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-lightbox/render-amp-lightbox.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-lightbox component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-lightbox' 10 | const canonical = 'https://amp-lightbox.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-lightbox', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-list/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 11 | 12 | ) 13 | } 14 | 15 | module.exports = Application 16 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-list/render-amp-list.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-list component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-list' 10 | const canonical = 'https://amp-list-serviceworker.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-list', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-live-list/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 10 | 13 |
14 |
16 |
17 | 21 |

A green landscape with trees.

22 |
23 |
24 |
25 |
26 |
27 | ) 28 | } 29 | 30 | module.exports = Application 31 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-live-list/render-amp-live-list.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-live-list component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-live-list' 10 | const canonical = 'https://amp-live-list-serviceworker.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-live-list', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-mathml/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | 3 | const Application = () => { 4 | return ( 5 | 6 | 7 | 8 | ) 9 | } 10 | 11 | module.exports = Application 12 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-mathml/render-amp-mathml.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const ampHtmlValidator = require('amphtml-validator') 3 | const Application = require('./Application') 4 | const ampReactRenderer = require('../../../dist/AmpHtmlRenderer.js') 5 | 6 | test('render a valid AMP page with amp-mathml component', async () => { 7 | // arrangement 8 | const AppComponent = 9 | const title = 'case - amp-mathml' 10 | const canonical = 'https://amp-mathml.test.com.tw' 11 | const headComponents = [] 12 | 13 | // action 14 | const htmlString = ampReactRenderer({ 15 | entryName: 'amp-mathml', 16 | AppComponent, 17 | title, 18 | canonical, 19 | headComponents 20 | }) 21 | 22 | // assertion 23 | expect.assertions(2) 24 | expect(htmlString).toMatchSnapshot() 25 | const validator = await ampHtmlValidator.getInstance() 26 | const result = validator.validateString(htmlString) 27 | console.log('amp validation result: ', result) 28 | expect(result.status).toEqual('PASS') 29 | }) 30 | -------------------------------------------------------------------------------- /tests/extensionComponents/amp-mustache/Application.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const { createMustacheTemplate } = require('react-ampify') 3 | 4 | const Application = () => { 5 | const templateString = 'Hello {{world}}!' 6 | return ( 7 | 8 |