diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000000..f0c67eba9d --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,68 @@ +## Local Development + +This document intends to establish a series of steps to take in order to set up a local environment for developing on the primereact components with live reload, quick builds, and incremental builds. + +## Instructions + +You must have a local copy of this repository somewhere on your machine. From that repository. Before starting, make sure that the version for your `primereact/package.json` is a [valid semantic version](https://docs.npmjs.com/about-semantic-versioning) and does not contain a suffix such as `-SNAPSHOT`. + +Once that is done, you will run: + +```shell +~/primereact/ $ npm run build:lib:dev +``` + +This will alter the bundler to only emit non-minified esm modules. The aliasing plugin has also been disabled for components. Once everything has been bundled (this can take a few minutes) you should keep this command running. It will allow for incremental builds as you develop in the `primereact/` directory. It will be finished when the terminal displays: `[20xx-xx-xx 00:00:00] waiting for changes...`. + +You will now `cd` into the `primereact/dist` directory and run: + +```shell +~/primereact/dist/ $ npm link +``` + +This will create a symlink in your global npm scope so that other local packages will rely on this version of primereact when built. You can verify that the package is linked by running this from the `primereact` directory. + +```shell +~/primereact/ $ npm ls -g --depth=0 --link=true + +/opt/homebrew/lib +└── primereact@XX.X.XX -> ./../../../Users/${user}/primereact/dist # <-- this must be in the dist/ dir !!! +``` + +**Reminder! the XX.X.XX version must be a valid [valid semantic version](https://docs.npmjs.com/about-semantic-versioning) that you are using in your local project** + +### Now change your directory to your local project you are developing on! + +```shell +~/primereact/dist/ $ cd ~/my-cool-project +~/my-cool-project/ $ +``` + +The goal now is to link your primereact dependency to the symlink that we configured earlier: + +```shell +~/my-cool-project/ $ npm link primereact +``` + +As long at the dependencies version that you symlinked satisfies the version that is specified in `my-cool-project/package.json` then the link should have worked. + +You can validate that by running: + +```shell +~/my-cool-project/ $ npm ls --link=true + +my-cool-project@0.0.0 /Users/${user}/my-cool-project +└── primereact@npm:dist@xx.x.xx -> ./../../primereact/dist # <-- this must be in the dist/ dir !!! +``` + +### Congratulations! + +You can now live develop in the `primereact/` directory and your changes should be represented in your `my-cool-project/` build. (Assuming you are running vite or another bundler for `my-cool-project`) + +### Cleanup + +Once done, you can cleanup with: + +```shell +~/primereact/ $ npm unlink +``` diff --git a/package.json b/package.json index 8de5e17478..814c47cc00 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,8 @@ "build": "next build", "build:lib": "NODE_ENV=production INPUT_DIR=components/lib/ OUTPUT_DIR=dist/ npm run build:package", "build:package": "npm run build:check && rollup -c && gulp build-resources && npm run build:api", + "build:lib:dev": "NPM_LINK=true NODE_ENV=production INPUT_DIR=components/lib/ OUTPUT_DIR=dist/ npm run build:package:dev", + "build:package:dev": "npm run build:check && rollup -c --watch && gulp build-resources && npm run build:api", "build:api": "npm run apiwebtypes && npm run apidoc", "build:check": "npm run lint && npm run format:check && npm run type:check && npm run security:check && (NODE_ENV=test npm run test:check)", "security:check": "npm audit --production --audit-level high", diff --git a/rollup.config.js b/rollup.config.js index 75197c5e60..20af6ab55f 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -15,6 +15,8 @@ let entries = []; let core = {}; +const NPM_LINK = process.env.NPM_LINK === 'true'; + // alias entries const ALIAS_ICON_COMPONENT_ENTRIES = [ { find: '../../iconbase/IconBase', replacement: 'primereact/iconbase' }, @@ -106,13 +108,13 @@ const GLOBAL_DEPENDENCIES = { const GLOBAL_COMPONENT_DEPENDENCIES = { ...GLOBAL_DEPENDENCIES, - ...ALIAS_COMPONENT_ENTRIES.reduce((acc, cur) => ({ ...acc, [cur.replacement]: cur.replacement.replaceAll('/', '.') }), {}) + ...(NPM_LINK ? [] : ALIAS_COMPONENT_ENTRIES.reduce((acc, cur) => ({ ...acc, [cur.replacement]: cur.replacement.replaceAll('/', '.') }), {})) }; // externals const EXTERNAL = ['react', 'react-dom', 'react-transition-group', '@babel/runtime', '@fullcalendar/core', 'chart.js/auto', 'quill']; -const EXTERNAL_COMPONENT = [...EXTERNAL, ...ALIAS_COMPONENT_ENTRIES.map((entries) => entries.replacement)]; +const EXTERNAL_COMPONENT = [...EXTERNAL, ...(NPM_LINK ? [] : ALIAS_COMPONENT_ENTRIES.map((entries) => entries.replacement))]; // plugins const BABEL_PLUGIN_OPTIONS = { @@ -156,11 +158,11 @@ const TERSER_PLUGIN_OPTIONS = { const PLUGINS = [replace(REPLACE_PLUGIN_OPTIONS), resolve(RESOLVE_PLUGIN_OPTIONS), commonjs(COMMONJS_PLUGIN_OPTIONS), babel(BABEL_PLUGIN_OPTIONS), postcss(POSTCSS_PLUGIN_OPTIONS)]; -const PLUGINS_COMPONENT = [alias(ALIAS_PLUGIN_OPTIONS_FOR_COMPONENT), ...PLUGINS]; +const PLUGINS_COMPONENT = NPM_LINK ? PLUGINS : [alias(ALIAS_PLUGIN_OPTIONS_FOR_COMPONENT), ...PLUGINS]; function addEntry(name, input, output, isComponent = true) { const exports = name === 'primereact.api' || name === 'primereact' ? 'named' : 'auto'; - const useCorePlugin = ALIAS_COMPONENT_ENTRIES.some((entry) => entry.replacement === name.replaceAll('.', '/')); + const useCorePlugin = !NPM_LINK && ALIAS_COMPONENT_ENTRIES.some((entry) => entry.replacement === name.replaceAll('.', '/')); const plugins = isComponent ? PLUGINS_COMPONENT : PLUGINS; const external = isComponent ? EXTERNAL_COMPONENT : EXTERNAL; const inlineDynamicImports = true; @@ -185,12 +187,16 @@ function addEntry(name, input, output, isComponent = true) { return { ...getEntry(isMinify), output: [ - { - format: 'cjs', - file: `${output}.cjs${isMinify ? '.min' : ''}.js`, - exports, - banner: "'use client';" // This line is required for SSR. - }, + ...(NPM_LINK + ? [] + : [ + { + format: 'cjs', + file: `${output}.cjs${isMinify ? '.min' : ''}.js`, + exports, + banner: "'use client';" // This line is required for SSR. + } + ]), { format: 'esm', file: `${output}.esm${isMinify ? '.min' : ''}.js`, @@ -217,11 +223,13 @@ function addEntry(name, input, output, isComponent = true) { }; entries.push(get_CJS_ESM()); - entries.push(get_IIFE()); + if (!NPM_LINK) { + entries.push(get_IIFE()); - // Minify - entries.push(get_CJS_ESM(true)); - entries.push(get_IIFE(true)); + // Minify + entries.push(get_CJS_ESM(true)); + entries.push(get_IIFE(true)); + } } function corePlugin() {