<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Anubhav</title>
    <description>The latest articles on DEV Community by Anubhav (@anukr98).</description>
    <link>https://dev.to/anukr98</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F636151%2F0ca4128c-facd-4e72-a0a3-3da0f1b3193c.jpeg</url>
      <title>DEV Community: Anubhav</title>
      <link>https://dev.to/anukr98</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anukr98"/>
    <language>en</language>
    <item>
      <title>Publishing your first enterprise-level NPM package</title>
      <dc:creator>Anubhav</dc:creator>
      <pubDate>Mon, 25 Sep 2023 19:21:44 +0000</pubDate>
      <link>https://dev.to/anukr98/publishing-your-first-enterprise-level-npm-package-37eb</link>
      <guid>https://dev.to/anukr98/publishing-your-first-enterprise-level-npm-package-37eb</guid>
      <description>&lt;p&gt;Warning: It's going to be a long read but the effort shall surely be worth the time is something I can guarantee!!&lt;/p&gt;

&lt;p&gt;As a developer, contributing to open-source is something everyone obviously wants to do but creating and publishing something of their own to the &lt;code&gt;npm registry&lt;/code&gt; is the penultimate challenge any developer wants to overcome.&lt;/p&gt;

&lt;p&gt;As such, we shall attempt to do the very same thing over in the following sections and that too in a manner that is not just a beginner approach but a completely professional and an industry-accepted way by which you can publish and document your creations on &lt;strong&gt;npm&lt;/strong&gt; and do an &lt;code&gt;npm i your_package_name&lt;/code&gt; anytime and anywhere you want and use it through both the &lt;strong&gt;ESM&lt;/strong&gt; way or the &lt;strong&gt;CJS&lt;/strong&gt; way.&lt;/p&gt;

&lt;p&gt;For the sake of an example, we shall attempt to publish a components library to the registry.&lt;/p&gt;

&lt;p&gt;We shall be making of the following tools to get our job done:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt;: needs no introduction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React Styleguidist&lt;/strong&gt;: An isolated React component development environment with a living style guide. It takes care of documenting all your components without you having to worry about the UI or linking or any other kind of functionality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rollup&lt;/strong&gt;: Similar to how Webpack or any bundler bundles your code into build files, Rollup compiles small and abstract code pieces into complex bundles served from a single location.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Typescript&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Material UI and Emotion&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;We begin with some configuration files:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a) tsconfig.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "compilerOptions": {
        "module": "ESNext",
        "allowSyntheticDefaultImports": true,
        "jsx": "react-jsx",
        "lib": ["ESNext", "DOM"],
        "moduleResolution": "Node",
        "declaration": true,
        "esModuleInterop": true,
        "noEmit": false,
        "skipLibCheck": true,
        "strict": true,
        "resolveJsonModule": true,
        "target": "ESNext",
        "inlineSourceMap": true,
        "rootDirs": ["src"],
        "baseUrl": ".",
        "jsxImportSource": "@emotion/react",
        "outDir": "dist",
        "typeRoots": ["node_modules/@types", "@types"]
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;b) tsconfig.esm.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "extends": "./tsconfig.build.json",
    "compilerOptions": {
      "declaration": false,
      "module": "ESNext",
      "outDir": "dist/esm"
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;c) tsconfig.cjs.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "extends": "./tsconfig.build.json",
    "compilerOptions": {
      "module": "CommonJS",
      "outDir": "dist"
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;d) tsconfig.build.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "extends": "./tsconfig.json",
    "compilerOptions": {
      "rootDir": "src"
    },
    "exclude": ["./build/**", "./dist/**", "./jest/**", "**/__tests__/**"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;e) styleguide.config.cjs&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"use strict";

const path = require("path");
const fs = require("fs");
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");

module.exports = {
  title: "Title of your components library",
  ignore: ["**/__tests__/**", "**/node_modules/**"],
  exampleMode: "expand",
  defaultExample: true,
  skipComponentsWithoutExample: true,
  styleguideComponents: {
    Wrapper: path.join(__dirname, "./src/theme-provider"),
  },
  pagePerSection: true,
  sections: fs
    .readdirSync("src")
    .filter(
      (path) =&amp;gt;
        fs.lstatSync(`src/${path}`).isDirectory() &amp;amp;&amp;amp;
        !path.startsWith(".") &amp;amp;&amp;amp;
        path !== "__tests__" &amp;amp;&amp;amp;
        fs.existsSync(`src/${path}/README.md`)
    )
    .map((dir) =&amp;gt; {
      const name = dir
        .split("-")
        .map((part) =&amp;gt; {
          if (part === "cta" || part === "nba") {
            return part.toUpperCase();
          }
          return `${part.charAt(0).toUpperCase()}${part.slice(1)}`;
        })
        .join("");
      return {
        name: name,
        content: `src/${dir}/README.md`,
        components: `src/${dir}/${name}.tsx`,
      };
    }),

  getComponentPathLine: (componentPath) =&amp;gt; {
    const componentName = path.basename(componentPath, ".tsx");

    return `import { ${componentName} } from "@your_org/your_package_name";`;
  },

  getExampleFilename: (componentPath) =&amp;gt; {
    const specificComponentExampleFile = path
      .join(path.dirname(componentPath), "./README.md")
      .replace();

    if (fs.existsSync(specificComponentExampleFile)) {
      return specificComponentExampleFile;
    }

    const exampleFile = path.join(componentPath, "../../README.md");

    if (fs.existsSync(exampleFile)) {
      return exampleFile;
    }

    return null;
  },

  propsParser: require("react-docgen-typescript").withCustomConfig(
    "./tsconfig.json"
  ).parse,

  webpackConfig: {
    entry: "./src/index.ts",
    module: {
      rules: [
        {
          test: /\.js(x?)$/,
          use: [
            {
              loader: "babel-loader",
              options: {
                presets: [
                  [
                    "@babel/preset-env",
                    {
                      modules: false,
                      targets: {
                        node: "current",
                      },
                    },
                  ],
                  "@babel/preset-react",
                ],
                env: {
                  production: {
                    presets: ["minify"],
                  },
                  test: {
                    presets: ["@babel/preset-env", "@babel/preset-react"],
                  },
                },
              },
            },
          ], // , 'source-map-loader'],
          exclude: /node_modules/,
        },
        {
          test: /\.ts(x?)$/,
          exclude: /node_modules/,
          use: [
            {
              loader: "ts-loader",
              options: {
                transpileOnly: true,
              },
            },
          ],
        },
        {
          test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
          exclude: /node_modules/,
          use: [
            {
              loader: "url-loader",
              options: {
                fallback: "file-loader",
                name: "[name].[ext]",
                outputPath: "fonts/",
                limit: 8192,
              },
            },
          ],
        },
        {
          test: /\.(png|jpg|gif)$/i,
          exclude: /node_modules/,
          use: [
            {
              loader: "url-loader",
              options: {
                limit: 8192,
              },
            },
          ],
        },
      ],
    },
    resolve: {
      extensions: [".ts", ".tsx", ".js"],
      plugins: [
        new TsconfigPathsPlugin({
          configFile: "./tsconfig.json",
        }),
      ],
    },
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now this is an important file to understand. In simple words, the styleguide config file handles how your guide interprets files and reads/parses them. The above configurations asks you to have an &lt;code&gt;src&lt;/code&gt; folder in your root, your theme to be in &lt;code&gt;src/theme-provider&lt;/code&gt;, and your entry file to be &lt;code&gt;src/index.ts&lt;/code&gt;.&lt;br&gt;
At the same time, it ensures that any and all files in all combinations of &lt;code&gt;README.md&lt;/code&gt; within each folder to become the documentation for that component and the root file to be the documentation of your complete project apart from a ton of other configurations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;f) rollup.config.mjs&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import commonjs from "@rollup/plugin-commonjs";
import resolve from "@rollup/plugin-node-resolve";
import typescript from "@rollup/plugin-typescript";
import url from "@rollup/plugin-url";
import svgr from "@svgr/rollup";
import peerDepsExternal from "rollup-plugin-peer-deps-external";
import { terser } from "rollup-plugin-terser";

export default [
  {
    input: "src/theme-provider/fonts/index.ts",
    output: [
      {
        file: `dist/theme-provider/fonts/index.js`,
        format: "cjs",
        sourcemap: true,
      },
      {
        file: `dist/esm/theme-provider/fonts/index.js`,
        format: "esm",
        sourcemap: true,
      },
    ],
    external: ["tslib"],
    plugins: [
      peerDepsExternal(),
      resolve(),
      commonjs(),
      typescript({ tsconfig: "./tsconfig.build.json", declaration: false }),
      svgr(),
      url({
        include: ["**/*.woff2"],
        // setting infinite limit will ensure that the files
        // are always bundled with the code, not copied to /dist
        limit: Infinity,
      }),
      terser(),
    ],
  },
];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the name goes, this obviously becomes the config for &lt;code&gt;rollup&lt;/code&gt; that we shall be using.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;g) package.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "@your_org/your_package_name",
  "version": "1.0.0",
  "main": "dist/index.js",
  "src": "src/index.ts",
  "module": "dist/esm/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "compile": "tsc",
    "build": "tsc -p tsconfig.cjs.json &amp;amp;&amp;amp; tsc -p tsconfig.esm.json &amp;amp;&amp;amp; rollup -c --bundleConfigAsCjs",
    "dev": "styleguidist server --config styleguide.config.cjs",
  },
  "license": "UNLICENSED",
  "files": [
    "dist/",
    "package.json"
  ],
  "typesVersions": {
    "*": {
      "theme-provider": [
        "./dist/theme-provider/index.d.ts"
      ],
      "button": [
        "./dist/button/index.d.ts"
      ],
    }
  },
  "exports": {
    ".": {
      "require": "./dist/index.js",
      "import": "./dist/esm/index.js",
      "types": "./dist/index.d.ts"
    },
    "./theme-provider": {
      "require": "./dist/theme-provider/index.js",
      "import": "./dist/esm/theme-provider/index.js",
      "types": "./dist/theme-provider/index.d.ts"
    },
    "./button": {
      "require": "./dist/button/index.js",
      "import": "./dist/esm/button/index.js",
      "types": "./dist/button/index.d.ts"
    },
  },
  "dependencies": {
    "@emotion/react": "^11.11.1",
    "@emotion/styled": "^11.11.0",
    "@mui/icons-material": "^5.14.0",
    "@mui/lab": "^5.0.0-alpha.136",
    "@mui/material": "^5.14.0",
    "@mui/styles": "^5.14.0",
    "@mui/system": "^5.14.0",
    "classnames": "^2.3.2",
    "react-is": "^18.2.0",
    "react-select": "^5.7.4"
  },
  "devDependencies": {
    "@babel/core": "^7.22.9",
    "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
    "@babel/plugin-transform-runtime": "^7.22.9",
    "@babel/preset-env": "^7.22.9",
    "@babel/preset-react": "^7.22.5",
    "@babel/preset-typescript": "^7.22.5",
    "@rollup/plugin-commonjs": "^25.0.4",
    "@rollup/plugin-node-resolve": "^15.2.1",
    "@rollup/plugin-typescript": "^11.1.3",
    "@rollup/plugin-url": "^8.0.1",
    "@svgr/rollup": "^8.1.0",
    "@types/classnames": "^2.3.1",
    "@types/node": "^20.5.1",
    "@types/react": "^18.2.20",
    "@types/react-dom": "^18.2.7",
    "@types/react-is": "^18.2.1",
    "babel-loader": "^9.1.3",
    "babel-plugin-react-remove-properties": "^0.3.0",
    "babel-preset-minify": "^0.5.2",
    "file-loader": "^6.2.0",
    "react": "^18.2.0",
    "react-docgen-typescript": "^2.2.2",
    "react-dom": "^18.2.0",
    "react-styleguidist": "^13.1.1",
    "rollup": "^3.28.1",
    "rollup-plugin-peer-deps-external": "^2.2.4",
    "rollup-plugin-terser": "^7.0.2",
    "ts-loader": "^9.4.4",
    "tsconfig-paths-webpack-plugin": "^4.1.0",
    "typescript": "^5.1.6",
    "url-loader": "^4.1.1",
    "webpack": "^5.88.1",
    "yalc": "^1.0.0-pre.53"
  },
  "peerDependencies": {
    "@emotion/react": "^11.10.8",
    "@emotion/styled": "^11.10.8",
    "@mui/icons-material": "^5.11.16",
    "@mui/lab": "^5.0.0-alpha.129",
    "@mui/material": "^5.12.3",
    "@mui/styles": "^5.12.3",
    "react": "&amp;gt;=16.8.0",
    "react-dom": "&amp;gt;=16.8.0"
  },
  "sideEffects": false
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obviously there's again a ton of things going on here but some of the most important takeaways from this file would be the following entries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;files&lt;/strong&gt;: These are the files that would actually be shipped away and made available to whoever installs your package.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;typesVersions and exports&lt;/strong&gt;: Post Node 16, TS corrected prioritising &lt;code&gt;typesVersions&lt;/code&gt; over &lt;code&gt;exports&lt;/code&gt;. As such, the said config ensures that your library works well for any project irrespective of the version of Node being utilised.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;With all setups now done, all that needs to be done is create an &lt;code&gt;src&lt;/code&gt; folder at the root level and subsequent folders for components within such as:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fafgzk0m2zj0u12ync8om.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fafgzk0m2zj0u12ync8om.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't forget that &lt;code&gt;src/index.ts&lt;/code&gt; is our entry file and so whatever we export from individual index.ts files of components has to be imported an subsequently exported from &lt;code&gt;src/index.ts&lt;/code&gt;. A little something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Button, {ButtonProps} from './button'

export {Button}
export type {ButtonProps}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have also configured &lt;code&gt;theme-provider&lt;/code&gt; to be used. Would have loved to share snippets for the same here but because it would not be possible, &lt;a href="https://github.com/Shethink/email-sequence-components/tree/master/src" rel="noopener noreferrer"&gt;here&lt;/a&gt; is a sample for how it would go about.&lt;/p&gt;




&lt;p&gt;Now that we are all done, it is &lt;strong&gt;FINALLY&lt;/strong&gt; time to publish our package which is simply a 2-step process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build the project using &lt;code&gt;yarn build&lt;/code&gt; or &lt;code&gt;npm run build&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Login to your npm account using &lt;code&gt;npm login&lt;/code&gt;. This is a one time process and need not be done every time. Make sure you login with the same user specified in the name of your &lt;code&gt;package.json&lt;/code&gt;. &lt;code&gt;@your_org&lt;/code&gt; in this case.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;npm publish --access public&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And &lt;em&gt;voila&lt;/em&gt; 🎉🎉🎉🎉&lt;br&gt;
Congratulations! Your package is now available on npm. Make sure to change the version number on every subsequent push to the registry.&lt;/p&gt;

&lt;p&gt;Congrats and thanks if you made it this far and please feel free to drop any queries or comments that you come across.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>npm</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>The end of an era: CRA thou shalt me be missed</title>
      <dc:creator>Anubhav</dc:creator>
      <pubDate>Mon, 10 Apr 2023 13:02:06 +0000</pubDate>
      <link>https://dev.to/anukr98/the-end-of-an-era-cra-thou-shalt-me-be-missed-13ga</link>
      <guid>https://dev.to/anukr98/the-end-of-an-era-cra-thou-shalt-me-be-missed-13ga</guid>
      <description>&lt;p&gt;Yes you heard that right! React officially parts ways with the much-coveted, much-used, and much-loved create-react-app.&lt;/p&gt;

&lt;p&gt;As a web developer, you can very confidently claim and say that React is probably &lt;strong&gt;THE&lt;/strong&gt; most powerful and versatile frameworks (library :p) available.&lt;/p&gt;

&lt;p&gt;And up till now &lt;code&gt;npx create-react-app&lt;/code&gt; has certainly been the go-to method/CLI for most of us to bootstrap and kickstart a new React project. However, with the constant evolution and fast-paced changes in the world of technology and development, even a tool such as React needs to keep up the pace just so it does not get left behind; the fist step for which was to ditch &lt;strong&gt;&lt;em&gt;CRA&lt;/em&gt;&lt;/strong&gt; and move towards a more robust solution all of which have been documented very eloquently in this &lt;a href="https://react.dev/"&gt;doc&lt;/a&gt; (oh which reminds me! React &lt;strong&gt;FINALLY&lt;/strong&gt; has a new documentation that moves away from the class-based paradigm and outdated information as compared to the original documentation).&lt;/p&gt;

&lt;p&gt;Although a final decision has not been made as to who shall be React's next date to the prom but they do have a bunch of options in consideration which are outlined in this new doc of theirs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a) NEXT.JS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's very difficult to see or imagine someone else take away the crown from Next.JS to be React's next partner to the big dance. It's increasing popularity amongst developers plugged in with its advanced features that solve a lot of React's shortcomings definitely make for a good bet for Next to be the next big thing.&lt;/p&gt;

&lt;p&gt;With server-side rendering for better performance and user experience to static website generation for better SEO, it's no surprise that React has chosen Next as its first choice for building all sorts of React-based projects using the &lt;code&gt;npx create-next-app&lt;/code&gt; CLI for setting up a new project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;b) REMIX&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Brought to you by &lt;a href="https://www.shopify.com/"&gt;Shopify&lt;/a&gt;, Remix although not too well known or used amongst the community, is gaining a lot of traction at a very rapid pace all thanks to its ton of unique features and capabilities.&lt;/p&gt;

&lt;p&gt;With SSR capabilities built-in and providing you an option to pick your deployment target, Remix could very well be an integral part of React moving forward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;c) GATSBY&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This one is brought to you by the much-loved and free CI/CD tool in the name and shape of &lt;a href="https://www.netlify.com/"&gt;Netlify&lt;/a&gt;. If you are looking to develop a CMS or want to have built-in and highly extensible GraphQL support, you need not look any further.&lt;/p&gt;

&lt;p&gt;With a plethora of simple and easy to hook plugins, Gatsby is making a strong stand for itself in terms of sustenance and shaping how we could perceive or work with React in the near future.&lt;/p&gt;




&lt;p&gt;To say that CRA is all but gonna be obsolete or become deprecated would be nothing short than overreacting. For all of its flaws and issues, the simplicity that CRA has offered to the community for so long can hardly ever be replaced. Sure there are a bunch of more performant and optimised solutions, CRA still leaves behind a legacy that would be hard to match!&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Setting up ESLINT with TS/JS in your React project in 2023</title>
      <dc:creator>Anubhav</dc:creator>
      <pubDate>Mon, 20 Mar 2023 11:01:11 +0000</pubDate>
      <link>https://dev.to/anukr98/setting-up-eslint-with-tsjs-in-your-react-project-in-2023-57o</link>
      <guid>https://dev.to/anukr98/setting-up-eslint-with-tsjs-in-your-react-project-in-2023-57o</guid>
      <description>&lt;p&gt;&lt;em&gt;ESLINT&lt;/em&gt;: Does not matter if you are a seasoned or a novice developer, ESLINT is definitely a term you have come across or heard of at the very least. Even I had heard of it a lot and even used it in applications that already had it configured but never had the liberty and or the chance to set it up on my own in a bare project. And that is exactly what we shall be doing today using the following tools:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ESLINT&lt;/strong&gt; is a pluggable linting tool for JS as well as JSX (basically React) which helps you detect possible errors in your code ranging from a wide array of possibilities such as unused variables in files, illegal comparisons, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PRETTIER&lt;/strong&gt; is probably the most popular code formatter to enforce a certain and consistent style guide in your codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HUSKY&lt;/strong&gt; in its own words is a simple tool to improve your commits and more by making use of &lt;a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks" rel="noopener noreferrer"&gt;git hooks&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  SETTING UP ESLINT
&lt;/h2&gt;

&lt;p&gt;It's as simple as running the following command in a terminal at the root of your project:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm init @eslint/config&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once you execute it, you will be prompted with a bunch of questions as follows:-&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ugk9xbv96z0or74owbq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ugk9xbv96z0or74owbq.png" alt="Image description" width="800" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Based on your requirements and environment, answer the questions accordingly. At least with eslint version 8.0.1, you are only presented with 2 style guides: &lt;a href="https://github.com/standard/eslint-config-standard" rel="noopener noreferrer"&gt;standard&lt;/a&gt; and &lt;a href="https://github.com/xojs/xo" rel="noopener noreferrer"&gt;XO&lt;/a&gt;.&lt;br&gt;
Personally, I prefer the standard styling guide but at any give time, it is a personal choice and as such feel free to choose any from a bunch of available options. Once all dependencies are installed, ensure that you have the following packages added as devDependencies to your project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@typescript-eslint/eslint-plugin&lt;/li&gt;
&lt;li&gt;@typescript-eslint/parser&lt;/li&gt;
&lt;li&gt;eslint &lt;/li&gt;
&lt;li&gt;eslint-config-standard-with-typescript&lt;/li&gt;
&lt;li&gt;eslint-plugin-import&lt;/li&gt;
&lt;li&gt;eslint-plugin-n&lt;/li&gt;
&lt;li&gt;eslint-plugin-promise&lt;/li&gt;
&lt;li&gt;eslint-plugin-react&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the time of writing this article, eslint latest version is 8.0.1 and there is a high chance that you may not get @typescript-eslint/parser added directly. If that is the case, do not worry. Just add the same as a dev dependency using&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i --save-dev @typescript-eslint/parser&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Following is a screenshot of the linter configuration that I work with. Feel free to go about the rules section and tweak it as per your flow. However, it is advisable that you do not go about changing the rules cause any style guide is written keeping certain things in mind but like all things, it is &lt;strong&gt;your&lt;/strong&gt; call ultimately.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

{
  "env": {
    "browser": true,
    "es2021": true
  },
  "extends": [
    "plugin:react/recommended",
    "standard-with-typescript",
    "plugin:import/typescript",
    "plugin:prettier/recommended"
  ],
  "parser": "@typescript-eslint/parser",
  "overrides": [],
  "parserOptions": {
    "ecmaVersion": "latest",
    "sourceType": "module",
    "project": "./tsconfig.json"
  },
  "plugins": ["react", "prettier"],
  "rules": {
    "@typescript-eslint/triple-slash-reference": "off"
  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: &lt;em&gt;Do remember to add a &lt;strong&gt;.eslintignore&lt;/strong&gt; file and keep non-essential files such as build, node_modules, dist, etc. in there otherwise the linter will keep yelling at you to fix those changes as well&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  SETTING UP PRETTIER
&lt;/h2&gt;

&lt;p&gt;This is comparatively a simple process cause most of the setup for prettier was already taken care of when we set up eslint and the related config file. Hit up the following command:-&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i --save-dev prettier eslint-config-prettier eslint-plugin-prettier&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add a &lt;strong&gt;.prettierrc.js&lt;/strong&gt; file as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

module.exports = {
  arrowParens: "avoid",
  bracketSameLine: true,
  bracketSpacing: false,
  singleQuote: false,
  trailingComma: "all",
  tabWidth: 2,
  useTabs: false,
  semi: true,
  printWidth: 80,
};


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Just like a &lt;strong&gt;.eslintignore&lt;/strong&gt;, add a &lt;strong&gt;.prettierignore&lt;/strong&gt; file containing elements that don't need to be checked&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Don't forget to check the &lt;strong&gt;format on save&lt;/strong&gt; setting in VSCode to allow prettier to enforce your changes automatically when you save your code&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  SETTING UP HUSKY**
&lt;/h2&gt;

&lt;p&gt;We are almost there. This is probably the trickiest and yet the easiest part of everything. The &lt;a href="https://typicode.github.io/husky/#/" rel="noopener noreferrer"&gt;Husky CLI&lt;/a&gt; makes it really easy to set things up. Once again, power up a terminal and run the following command:-&lt;br&gt;
&lt;code&gt;npx husky-init &amp;amp;&amp;amp; npm install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This creates a &lt;strong&gt;.husky&lt;/strong&gt; folder at your root level with an existing file called &lt;em&gt;pre-commit&lt;/em&gt; and this is the file where you want to add some things so that your codebase is scanned for issues before you are able to commit your code. But before we jump to this file, you wanna edit the &lt;strong&gt;scripts&lt;/strong&gt; part of your &lt;strong&gt;package.json&lt;/strong&gt; by adding the following lines:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

"lint": "eslint .",
"lint:fix": "eslint --fix .",
"prettier": "prettier --write .",


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once this is done, you head over to the pre-commit file discussed earlier and add a simple line over there:&lt;br&gt;
&lt;code&gt;npm run lint&lt;/code&gt;&lt;br&gt;
which ultimately translates that before you commit your changes, run the lint script as specified in the package.json file.&lt;/p&gt;

&lt;p&gt;To be absolutely sure of things, before committing your code, run the following commands in order: &lt;br&gt;
&lt;code&gt;npm run prettier&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm run lint:fix&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;These will make sure that your code is at least formatted properly and devoid of as many errors that eslint could have fixed automatically for you. If you still see errors on your terminal, head over to the erroneous files and fix the issues manually and then only can you move forward with committing your code.&lt;/p&gt;




&lt;p&gt;And that wraps it up. You are all done towards making and keeping your code well maintained. &lt;strong&gt;HAPPY HACKING!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>M1 and React Native (Not a headache)</title>
      <dc:creator>Anubhav</dc:creator>
      <pubDate>Fri, 26 Aug 2022 07:23:00 +0000</pubDate>
      <link>https://dev.to/anukr98/m1-and-react-native-not-a-headache-220n</link>
      <guid>https://dev.to/anukr98/m1-and-react-native-not-a-headache-220n</guid>
      <description>&lt;p&gt;For anyone who has worked on or works on React Native, there's no denying that iOS setup, development, and distribution is &lt;strong&gt;FAR FAR FAR&lt;/strong&gt; more difficult than that of Android.&lt;br&gt;
The situation kinda takes a turn for worse with the new CPU architecture, &lt;em&gt;viz.&lt;/em&gt; M1 that Apple rolled out a year or two back. There's no denying that M1 is no less than a tech marvel and we don't expect anything less from Apple; but you sure wanna yell out a couple of words out loud to an architecture that just refuses to run a couple of basic commands that used to run as smooth as butter previously.&lt;/p&gt;

&lt;p&gt;The most common issue that pops up with this new architecture is the very simple command we execute known as:&lt;br&gt;
&lt;code&gt;pod install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can expect all pods to be installed without any hiccups but the pods that cause an issue in their installation are:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;boost&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;glog&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's tackle these issues one by one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BOOST&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Installing pods for boost results in an error similar to =&amp;gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feqtew07rn7qqv7i22tfx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feqtew07rn7qqv7i22tfx.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In short, the error states that it could not place an authorised request to &lt;code&gt;jfrog.io&lt;/code&gt; and is crashing with a 401 unauthorised request. The solution to this couldn't be simpler. Just execute the following command and you're golden:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ios &amp;amp;&amp;amp; rm -rf Pods &amp;amp;&amp;amp; rm -rf Podfile.lock &amp;amp;&amp;amp; rm -rf build &amp;amp;&amp;amp; pod deintegrate &amp;amp;&amp;amp; cd ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have done this, pod install should move past installation of boost and then hang up on &lt;code&gt;glog&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;PS: You might run into many solutions asking you to install the ffi gem and execute a command like&lt;br&gt;
             &lt;code&gt;sudo arch -x86_64 gem install ffi&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You may give it a whirl but it definitely fails (at least it did for us saying that &lt;strong&gt;&lt;em&gt;the architecture specified is invalid&lt;/em&gt;&lt;/strong&gt;) so there's no absolute guarantees that this would most certainly work.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GLOG&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pod installation for glog mostly crashes with an error that looks something like:&lt;br&gt;
&lt;code&gt;error: C compiler cannot create executables&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once again, the solution is pretty simple. This time instead of one though, we wanna execute 2 commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo xcode-select --switch /Applications/Xcode.app
cd ios &amp;amp;&amp;amp; pod install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;.&lt;/p&gt;

&lt;p&gt;Here's one to hoping this article proves helpful for you :D&lt;br&gt;
If you are facing any other issues or if the aforementioned solutions don't seem to pan out for you, feel free to drop the same in the comments down so we may take it forward.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>ios</category>
      <category>mobile</category>
      <category>apple</category>
    </item>
    <item>
      <title>Context + Hooks &gt; React + Redux</title>
      <dc:creator>Anubhav</dc:creator>
      <pubDate>Thu, 24 Jun 2021 10:50:43 +0000</pubDate>
      <link>https://dev.to/anukr98/context-hooks-react-redux-9n6</link>
      <guid>https://dev.to/anukr98/context-hooks-react-redux-9n6</guid>
      <description>&lt;p&gt;Amongst the dev community, one of the most hot and trending technology these days has got to be React and regardless of how you feel about working with it, you have to give it credit for at-least feeling like a full-blown framework despite being a library.&lt;br&gt;
Redux has been the library of choice for global state management for years now but it's high time now that we move forward. The primary reason for this being the verbosity of Redux that not just make it a tad cumbersome to use but also kind of senseless unless you are working on an enterprise-level project.&lt;/p&gt;
&lt;h1&gt;
  
  
  CONTEXT API
&lt;/h1&gt;

&lt;p&gt;React 16 gave us a wonderful solution to global state management =&amp;gt; &lt;strong&gt;Context API&lt;/strong&gt;. A library with syntax very similar to Redux but with exponentially less boilerplate and setup.&lt;br&gt;
Using Context is pretty straightforward. A &lt;code&gt;Provider&lt;/code&gt; serves the values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
const StateContext = React.createContext(/* default state */);
const App = props =&amp;gt; (
  &amp;lt;StateContext.Provider value={{ color: green }}&amp;gt;
    {props.children}
  &amp;lt;/StateContext.Provider&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And a &lt;code&gt;Consumer&lt;/code&gt; uses the values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const ConsumerComponent = () =&amp;gt; (
  &amp;lt;StateContext.Consumer&amp;gt;
    {value =&amp;gt; (
      &amp;lt;Button primaryColor={{ value.color }}&amp;gt;Consumer&amp;lt;/Button&amp;gt;
    )}
  &amp;lt;/StateContext.Consumer&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This implementation shall, however, work only for &lt;code&gt;functional components&lt;/code&gt;. There are other ways to access context values in class-based components. You may read up on those in the &lt;a href="https://reactjs.org/docs/context.html"&gt;official React docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;h1&gt;
  
  
  HOOKS
&lt;/h1&gt;

&lt;p&gt;Soon after the Context API was released in production, &lt;code&gt;hooks&lt;/code&gt; were introduced and things were never the same again. It was not just state management that benefited but React in its entirety saw a much-needed overhaul from all the classes that we used to write previously.&lt;br&gt;
Out of the 10 default hooks that React ships with, the &lt;code&gt;useReducer&lt;/code&gt; hook can be used to set up Context API within our app. The useReducer hook takes 2 arguments; namely a &lt;code&gt;reducer function&lt;/code&gt; and an &lt;code&gt;initial state&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useReducer } from 'React';

const reducer = (state, action) =&amp;gt; {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };

    default:
      return state;
  }
};

const IncrementComponent = ({ initialCount }) =&amp;gt; {
  const [state, dispatch] = useReducer(reducer, { count: 0 });  return (
    &amp;lt;button onClick={() =&amp;gt; dispatch({ type: 'increment'})}&amp;gt;
      Increment: {state.count}
    &amp;lt;/button&amp;gt;
  );
} ;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This syntax looks awfully similar to Redux. Cool right!&lt;br&gt;
The useReducer hook returns the &lt;code&gt;[state, dispatch]&lt;/code&gt; array where &lt;code&gt;state&lt;/code&gt; is the current state you can consider &lt;code&gt;dispatch&lt;/code&gt; to be like a gun that shoots actions at our data layer. You can call it anything but while looking at a Redux substitute, we can use its naming convention at the very least!&lt;br&gt;
Every time the &lt;code&gt;dispatch&lt;/code&gt; method is called, the reducer function is triggered which matches your action type and updates the state as per the payload you send to it.&lt;/p&gt;

&lt;p&gt;Now for the fun part!&lt;/p&gt;
&lt;h1&gt;
  
  
  HOOKS + CONTEXT
&lt;/h1&gt;

&lt;p&gt;Using Context and hooks together allows you to make your own global state management system in hardly 10 lines of code. Intrigued right because that would be pretty neat!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React , { createContext , useContext , useReducer } from 'react';

export const StateContext = createContext();

export const StateProvider=({ reducer , initialState , children })=&amp;gt;(
    &amp;lt;StateContext.Provider value = {useReducer(reducer,initialState)}&amp;gt;
        {children}
    &amp;lt;/StateContext.Provider&amp;gt;
);

export const useStateValue = () =&amp;gt; useContext(StateContext)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et voila. We're done! Let's see what's happening here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;createContext&lt;/code&gt; creates a context object and returns it to StateContext which stores the &lt;code&gt;Provider&lt;/code&gt; and the &lt;code&gt;Consumer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Next we create StateProvider which is basically a HOC which wraps its children with the values offered by the Provider.&lt;/li&gt;
&lt;li&gt;Finally we create &lt;code&gt;useStateValue&lt;/code&gt; which is a &lt;code&gt;custom hook&lt;/code&gt; which uses the StateContext &lt;code&gt;context&lt;/code&gt;. We did this because otherwise you would have to import &lt;code&gt;useContext&lt;/code&gt; and &lt;code&gt;StateContext&lt;/code&gt; in all places wherever you wanted access to these values. Building up on the DRY principle of coding, we created a universal hook to take care of the same once and for all.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...&lt;br&gt;
Next we just need a reducer and an initial state to start using the &lt;code&gt;StateProvider&lt;/code&gt; component. We already took a look at what a &lt;code&gt;reducer&lt;/code&gt; could look like earlier. The &lt;code&gt;initial state&lt;/code&gt; can be anything you want; a JSON object, an array, or whatever fits your purposes the best.&lt;/p&gt;

&lt;p&gt;Now let's see how to use the &lt;code&gt;StateProvider&lt;/code&gt; component and we're all set. In our entry file (generally App.js), we just need to wrap our return block with the StateProvider =&amp;gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { StateProvider } from './utils/StateProvider';
import reducer, { initialState } from './utils/reducer';

const App = () =&amp;gt; {
  return (
    &amp;lt;StateProvider initialState={initialState} reducer={reducer}&amp;gt;
        // Content ...
    &amp;lt;/StateProvider&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  SIDE NOTE
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;To now access the state values inside your component, you simply go like:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useStateValue } from '../utils/StateProvider'

const MyComponent = () =&amp;gt; {
    const [state, dispatch] = useStateValue()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can always use object destructing to just get the required slices of data from your global state instead of getting the entire state.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This implementation is viable only for functional components because &lt;code&gt;useStateValue&lt;/code&gt; under the hood use the &lt;code&gt;useContext&lt;/code&gt; hook and the rules of hooks clearly state that &lt;code&gt;hooks can only be called inside the body of a functional component&lt;/code&gt;.
If you want to use these values in a &lt;code&gt;class-based component&lt;/code&gt;, you shall have to go over the bit more verbose method of using Consumer or &lt;code&gt;contextType&lt;/code&gt; but in modern times, working with functional components is the norm and there's no way that this implementation shall break any time in the future.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>redux</category>
    </item>
  </channel>
</rss>
