Products

Solutions

Resources

Partners

Community

Blog

About

New Community Website

Ordinarily, you'd be at the right spot, but we've recently launched a brand new community website... For the community, by the community.

Yay... Take Me to the Community!

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.


Upgrading Persona Bar Components for DNN 9.3

Upgrading Persona Bar Components Guide

Overview

For version 9.3 of DNN Platform all the persona bar components in the Persona Bar have been upgraded to React 16. The Persona Bar has also been updated to use the new DNN React Common components, which have also been upgraded to React 16.

If you currently have any Persona Bar components that you have developed you will need to update them to the latest version of React as well as update to the latest DNN React Common components. This post is a guide to help you accomplish that.

How Does the Persona Bar Work?

Currently the Persona Bar loads JQuery and RequireJS. It also loads a bundle called export-bundle.js. This bundle contains React and all the supporting components. When a menu item in the Persona Bar is clicked RequireJS dynamically pulls the bundle file for the requested menu item. Once the bundle is loaded it executes using the dependencies that were loaded by export-bundle.js.

Getting Setup and Installing the Tools


There are several tools that will need to be installed on your machine to upgrade a Persona Bar project. You will need node, yarn at a minimum. I also recommend installing npm-check-updates and react-codemod as they make updating the package references really easy.

Node JS

You can download and install Node JS from [here][https://nodejs.org/].

Yarn

Once you have node installed, you can install yarn. Use the instructions here to install yarn on your platform.

NPM Check Updates

Run the following from a command prompt

yarn global add npm-check-updates

React Code Mod

Finally you will need to install react-codemod. This is a GitHub repository that allows you to run various commands on React projects. To install react-codemod

  1. yarn global add jscodeshift
  2. git clone https://github.com/reactjs/react-codemod.git or download a zip file from https://github.com/reactjs/react-codemod/archive/master.zip
  3. Run yarn install in the react-codemod directory
  4. jscodeshift -t <codemod-script> <path>
    • codemod-script - path to the transform file, see available scripts below;
    • path - files or directory to transform;
    • use the -d option for a dry-run and use -p to print the output for comparison;
    • use the --extensions option if your files have different extensions than .js (for example, --extensions js,jsx);
    • if you use flowtype, you might also need to use --parser=flow;
    • see all available jscodeshift options.

You can view all the possible react-codemod scripts at the GitHub repository.

Start Updating Your Component


Once you have all the tools installed go into your component

Check for Updates

Once you are in the correct folder it is time to start updating the component.

  1. Remove the existing yarn.lock file
  2. Check for updates
    yarn upgrade
    ncu -u
  3. Remove existing babel plugins:
    yarn remove babel-core babel-plugin-transform-object-assign      babel-plugin-transform-object-rest-spread babel-preset-es2015 babel-preset-react
  4. Add new babel plugins:
    yarn add @babel/[email protected]^7.1.6 @babel/plugin-proposal-object-rest-[email protected]^7.0.0 @babel/plugin-transform-object-[email protected]^7.0.0 @babel/preset-[email protected]^7.1.6 @babel/preset-[email protected]^7.0.0 -D 
  5. Add prop-types, webpack-cli
    yarn add [email protected]^15.6.2 [email protected]^3.1.2 -D
  6. Update the .babelrc file. Just copy and paste the following:
    {
    "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
    ],
    "plugins": [
    "@babel/plugin-transform-object-assign",
     "@babel/plugin-proposal-object-rest-spread",
     "react-hot-loader/babel"
    ],
    "env": {
    "production": {
      "plugins": [
        "transform-react-remove-prop-types"
      ]
    }
    }
    }
  7. Update the .eslintrc.js file.
    • Add the "settings" section
      ...
      "extends": ["eslint:recommended", "plugin:react/recommended"],
      "settings": {
        "react": {
          "version": "16"
        }
      },
      ...
    • Set the parserOptions and ecmaVersion
      ...
      "parserOptions": {
        "ecmaFeatures": {
            "jsx": true,
            "arrowFunctions": true,
            "blockBindings": true,
            "classes": true,
            "defaultParams": true,
            "destructuring": true,
            "forOf": true,
            "generators": true,
            "modules": true,
            "objectLiteralComputedProperties": true,
            "regexUFlag": true,
            "regexYFlag": true,
            "spread": true,
            "superInFunctions": false,
            "templateStrings": true
        },
        "ecmaVersion": 2018,
        "sourceType": "module"
      },
      ...
  8. Upgrade the webpack.config.js file There are several instructions online about upgrading webpack configuration files to webpack 4. This will only be a brief overview. You can also look at the webpack.config.js file in Dnn.AdminExperience\Extensions\Manage\Dnn.PersonaBar.Roles\Roles.Web for reference.

    • Add optimization
      ...
      entry: "./src/main.jsx",
      optimization: {
        minimize: isProduction
      },
      ...
    • Resolve the output path
      ...
      output: {
        path: path.resolve("../admin/personaBar/scripts/bundles/"),
      ...
      },
      ...
    • Update the module section to remove loaders and preLoaders. The final section should look similar to
      module: {
        rules: [
            { test: /\.(js|jsx)$/, enforce: "pre", exclude: /node_modules/, loader: "eslint-loader", options: { fix: true } },
            { test: /\.(js|jsx)$/ , exclude: /node_modules/, loaders: ["babel-loader"] },
            { test: /\.(less|css)$/, loader: "style-loader!css-loader!less-loader" },
            { test: /\.(ttf|woff)$/, loader: "url-loader?limit=8192" },
            { test: /\.(gif|png)$/, loader: "url-loader?mimetype=image/png" },
            { test: /\.woff(2)?(\?v=[0-9].[0-9].[0-9])?$/, loader: "url-loader?mimetype=application/font-woff" },
            { test: /\.(ttf|eot|svg)(\?v=[0-9].[0-9].[0-9])?$/, loader: "file-loader?name=[name].[ext]" },
        ]
      },
    • Alter the resolve section
      ...
      resolve: {
        extensions: [".js", ".json", ".jsx"],
        modules: [
            path.resolve("./src"),          // Look in src first
            path.resolve("./node_modules")  // Last fallback to node_modules
        ]       
      },
      ...
    • Remove the UglifyJsPlugin and DedupePlugin from the plugins section
  9. Install all the dependencies and regenerate the yarn.lock file

    yarn install
  10. Alter the jsx files to use PropTypes instead of React.PropTypes This is where the react-codemod script comes in handy. At the command prompt navigate to where you installed the react-codemod repository and run
    jscodeshift -t react-codemod/transforms/React-PropTypes-to-prop-types.js <path> --extensions js,jsx
    Reaplacing the <path> with the path to your components src directory. For example to run this on the Roles component, where the Dnn.AdminExperience project is located at C:\git\Dnn.AdminExperience, you would run
    jscodeshift -t react-codemod/transforms/React-PropTypes-to-prop-types.js C:\git\Dnn.AdminExperience\Extensions\Manage\Dnn.PersonaBar.Roles\Roles.Web --extensions js,jsx
    If you want to see what files the script is going to alter then you can add the options -d -p to the command.
  11. Build the component and fix any errors and warnings that appear.

    yarn run build

    Some of the most common errors that appear are:

    • Do not use findDOMNode
    • string refs are not allowed
    • componentWillMount is deprecated
    • componentWillReceiveProps is deprecated

    To correct the string refs are not allowed and the findDOMNode error please refer to the following post. Rule proposal: warn against using findDOMNode()

    To correct the deprecated react lifecycle errors please refer to the following post. Migrating from Legacy Lifecycles

  12. Test your component You should have a component that builds now. Once the bundle is built, copy it into a local DNN instance at the proper file location and attempt to access it from the Persona Bar. Once the component comes up, test everything related to that component.

Upgrading to the Latest Dnn.React.Common Components Library


Why was the Library Restructured

The library was restructured to make development against the react components simpler as well as to save space due to the node_modules folder being installed on every single component.

The component library is now being published on npm.js so you no londer have to add references to myget.

Installation

yarn add @dnnsoftware/dnn-react-common -D

Update the webpack.config.js

If you are using the DNN React Common components as external references you will need to update your webpack.config.js file to use the new path.

externals: require("@dnnsoftware/dnn-react-common/WebpackExternals"),

Update your components

Search for all files with from “dnn- Go to each file and replace the import statements with a import like the following using the components you are replacing

Import { SvgIcons, Button, Label, SingleLineTextBoxWithError } from “@dnnsoftware/dnn-react-common”;

Update your CSS References

Anywhere you reference the old dnn-global-styles component you will need to replace that reference with the following:

@import "[email protected]/dnn-react-common/styles/index";

Things that changed

If you get a JavsScript error during rendering of your component that says: Error: Minified React error #130

It means that one of the components you have referenced has an incorrect name. A few of the components had to have their names changed. Take a look at the following list:

Collapse -> Collapsible or CollapsibleRow 

DropDown -> Dropdown 

SvgIcons -> You must prefix the icon name with SvgIcons. E.g. ArrowBack -> SvgIcons.ArrowBack 

Tabs -> DnnTabs OverflowWrapper -> TextOverflowWrapper


Closing Statements

This seems like an awful lot to go through to upgrade the projects. However, these steps go fairly quickly and the effort is worth it. Going forward the community will need to decide how often React and the supporting components will be updated. We will need to do this fairly often so we do not have to go through this large update again!

Comments

David Poindexter
Great blog Matt - thanks so much for the work on formatting this as a guide to others!
David Poindexter Saturday, January 12, 2019 11:28 AM (link)
Fuji Nguyen
To build SPA modules in DNN, is React the way to go? Is Angular a possible option?
Fuji Nguyen Sunday, January 13, 2019 6:19 AM (link)
David Poindexter
Fuji, this blog post is more about Persona Bar extensions in DNN. There are many extension points in DNN, and this is just one of them. "SPA modules" are meant to live on a page as a DNN "module" (not within the Persona Bar).

That said, SPA modules can be built with any framework desired, or no framework at all. There are quite a few open source examples out there, but here is one to show the same solution developed as a SPA module, and MVC module, a WebForms module and even a PersonaBar extension.

https://github.com/DotNetNuclear/DnnRestaurantMenu

You can find many more open source DNN projects via nvQuickPulse (mobile app available on Apple and Google Play stores).
David Poindexter Monday, January 14, 2019 7:04 AM (link)
Clint Patterson
Thanks to everyone who contributed to this effort, the community is appreciative! And thanks Matt for this blog... great stuff!
Clint Patterson Monday, January 14, 2019 1:26 PM (link)

Comment Form

Only registered users may post comments.

NewsArchives


Aderson Oliveira (22)
Alec Whittington (11)
Alessandra Davies (3)
Alex Shirley (10)
Andrew Hoefling (3)
Andrew Nurse (30)
Andy Tryba (1)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (37)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Bogdan Litescu (1)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (213)
Chris Paterra (55)
Clint Patterson (108)
Cuong Dang (21)
Daniel Bartholomew (2)
Daniel Mettler (181)
Daniel Valadas (48)
Dave Buckner (2)
David Poindexter (12)
David Rodriguez (3)
Dennis Shiao (1)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (80)
Francisco Perez Andres (17)
Geoff Barlow (12)
George Alatrash (12)
Gifford Watkins (3)
Gilles Le Pigocher (3)
Ian Robinson (7)
Israel Martinez (17)
Jan Blomquist (2)
Jan Jonas (3)
Jaspreet Bhatia (1)
Jenni Merrifield (6)
Joe Brinkman (274)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Kelly Ford (4)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matt Rutledge (2)
Matthias Schlomann (16)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Miguel Gatmaytan (3)
Mike Horton (19)
Mitchel Sellers (40)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Oliver Hine (1)
Patricio F. Salinas (1)
Patrick Ryan (1)
Peter Donker (54)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Sacha Trauwaen (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott S (11)
Scott Wilkinson (3)
Scott Willhite (97)
Sebastian Leupold (80)
Shaun Walker (237)
Shawn Mehaffie (17)
Stefan Cullmann (12)
Stefan Kamphuis (12)
Steve Fabian (31)
Steven Fisher (1)
Timo Breumelhof (24)
Tony Henrich (3)
Torsten Weggen (3)
Tycho de Waard (4)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (40)
Will Strohl (180)
William Severance (5)
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out