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
.
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
yarn global add jscodeshift
git clone https://github.com/reactjs/react-codemod.git
or download a zip file from https://github.com/reactjs/react-codemod/archive/master.zip
- Run
yarn install
in the react-codemod directory
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.
- Remove the existing
yarn.lock
file
- Check for updates
yarn upgrade
ncu -u
- 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
- Add new babel plugins:
yarn add @babel/core@^7.1.6 @babel/plugin-proposal-object-rest-spread@^7.0.0 @babel/plugin-transform-object-assign@^7.0.0 @babel/preset-env@^7.1.6 @babel/preset-react@^7.0.0 -D
- Add
prop-types
, webpack-cli
yarn add prop-types@^15.6.2 webpack-cli@^3.1.2 -D
- 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"
]
}
}
}
- 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"
},
...
-
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
-
Install all the dependencies and regenerate the yarn.lock
file
yarn install
- 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>
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.
-
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
- 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 "~@dnnsoftware/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!