Packaging react-use-please-stay as an npm Module using Rollup
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
Lesson Transcript
[00:00 - 00:19] The size of our codebase is already expanding, and we can imagine how cumbersome it will be to continually modify and run our copyhook script in our example project. Let's package our code as an NPM module so we can use it directly in our example app via NPM link.
[00:20 - 00:23] We will now install three packages as dev dependencies. The first is rollup.
[00:24 - 00:50] The second is the standard TypeScript plugin for rollup, and the third is TSlib , which is required by the TypeScript rollup plugin. So that is NPM install, save dev, rollup, then the rollup plugin, TypeScript, and TSlib.
[00:51 - 01:18] Now we'll create a rollup.config.js file in the project root, and within this file we'll first import the TypeScript plugin. We'll import the package as PKG from package.json.
[01:19 - 01:37] We can't use the word package directly since that's a reserved word, and we'll also need to assert TypeJSON for a JSON import. And here we'll set up our config.
[01:38 - 01:45] So we're going to export default. First we need to define an input for rollup to go off of.
[01:46 - 02:05] That will be an index.ts file, which we have yet to make. And the output for the file will use the package.json main key.
[02:06 - 02:18] It's going to be a module. We do want source maps, and we'll set strict to false.
[02:19 - 03:00] We need to pass in the TypeScript plugin, which is a function, and the external library that we're using is React. Next we need to update our build script, and instead of using TSC, our build script becomes rollup-c.
[03:01 - 03:10] The dash c flag tells rollup to use our rollup config file when packaging. Finally we'll need to expose the files that we want to package.
[03:11 - 03:24] In this case, the usepleasestay.ts file. And to do that, we'll create a new index.ts file right in the src root.
[03:25 - 03:35] And from here we'll just export usepleasestay from hooks. Use pleasestay.
[03:36 - 03:53] We'll also need to allow synthetic default imports for rollup to work, since React itself is a synthetic default import. So we'll need to add that to our TS config.
[03:54 - 04:04] And we'll also set declaration to true. That means TypeScript will create a type declaration for us when rollup does its building.
[04:05 - 04:28] And outside of the compiler options, we should also be sure to define and tell the TypeScript compiler which files we want to include and those who wish to exclude during the build process. And for us, we'd like to include the src folder and we'd like to be sure to exclude the example folder.
[04:29 - 04:43] Since our usepleasestay hook is about to become an mpm module, we need to inform mpm of this within package.json. We can do that by adding type module to the JSON.
[04:44 - 04:54] And while we're in package.json, we should also update the main value here. As you remember, we're using it in our config to specify the output file.
[04:55 - 05:14] And so if we were to leave it as index.js, our distribution version would be built directly in the root folder, which is not what we want, but rather we'd like to target the dist folder. So that can be updated by adding dist in front of the index.js file.
[05:15 - 05:23] Let's now try packaging our hook with our new build command. So it looks like our build is working fine.
[05:24 - 05:31] And to double check, we can look in the dist folder. We should have the following files and folders within hooks.
[05:32 - 05:48] We should have the type declaration for both use interval and usepleasestay. And in the root of dist, we should have three files, the type declaration, the actual distributable index of the hook and the source map file.
[05:49 - 05:58] If you still have usepleasestay.js in this folder, you should delete it. So I will also delete it.
[05:59 - 06:20] Now to be able to use mpm link, we have to make a few more properties in package.json. First, since this is a module with types, thanks to typescript's type declaration files, we should also specify the types property as dist index.d.ts.
[06:21 - 06:27] We then should also provide the files property. This tells mpm all relevant files needed for our package.
[06:28 - 06:45] In our case, it's the dist folder where rollup placed all our package files. mpm expects this to be an array, so we will pass it, so we will be sure to pass it as an array.
[06:46 - 07:00] And with that done, we should now be able to run mpm link. Before we can use this linked package in our example app, we need to be sure to link to a single version of React.
[07:01 - 07:14] In our case, we want the version of React that is used in the example folder. Ensuring that you're still inside the root directory, we can link to the React version present in the node modules folder of the example project.
[07:15 - 07:38] So that would be npm link, the example folder, known modules, and React. Now we can move into the example folder and link our package.
[07:39 - 08:03] To double check that the link worked, you can issue npmls, location global, depth, zero, and link true. Now let's run our example app to see if everything is still working as expected .
[08:04 - 08:14] Now that the app's up and running, we do still see the title toggling effect just as we had in the previous lesson. So it looks like everything is working.
[08:15 - 08:38] As a cleanup within the example app's package.json, we can get rid of our copy hook script and also delete the hooks folder from the project. In summary, we installed rollup, the TypeScript plugin, and TSlib.
[08:39 - 08:51] We created a rollup config file that gives rollup the instructions to package our hook. We created an index.ts file to expose our hook file.
[08:52 - 09:10] We modified our package.json file and set important properties needed to package our hook. We linked our package to our example project, and we finally imported our hook directly from our linked package and ran our example project to make sure that everything was working.
[09:11 - 09:14] In the next lesson, we will clean up and refactor what we have built so far.