Reusable Svelte component: so no one gets hurt

Reusable Svelte component: so no one gets hurt







Component frameworks, regardless of name, will never leave the area of ​​purely niche use unless the community creates public components for them that you can easily embed into your project.







Over the past year and a half, many different components have already been created for the Svelte framework, which can be found on NPM , GitHub or the official list . Unfortunately, not all of them are properly "cooked" and sometimes using them will inflate the application bundle more than it should. And it happens that such packages are simply impossible to use, because its author is not good at preparing packages and missed some important points.







In this article I will show you how to make and publish an npm package with a Svelte component so that everyone can use it without getting headaches from unexpected problems.







Create a component



For example, let's decide that we want to present to the world a component that displays a clock with an animation of changing numbers. Let's take a look at its prototype at work here . Note that our entire component consists of three files. It also has an external dependency in the form of a library 'dayjs'



.







Animated clock







First you need an empty folder. Having opened it in the terminal, we initialize the creation of a new npm package:







  npm init
      
      





, . , Svelte-, svelte-



, , , svelte-clock-demo



. , . , . , Enter.







, package.json



, components



, 'App.svelte'



,'Sign.svelte'



'flip.js'



.







list of files







, :







  npm install dayjs
      
      





Svelte-, , . package.json



"main":"index.js",



:







 ...
 "svelte":"components/App.svelte",
 ...
      
      





, , . – ...









, Svelte- c , "svelte"



package.json



. , , - . Svelte .







ES6 Webpack Rollup. JavaScript Svelte-, CSS-, . , svelte



, , svelte/transition



svelte/store



, svelte/internal



. , , Svelte, .







IIFE <script src="...">



. html-, - CDN, jsdelivr.com unpkg.vom. , , , svelte



, – , dayjs



.







. – Webpack, Rollup, Parcel . , esbuild, Go, , tree- . esbuild-svelte



svelte



. dev-:







 npm install --save-dev esbuild esbuild-svelte svelte
      
      





svelte



dev-, Javascript-. , svelte



. , , , , ES6 , . , package.json



peer-.







...,

"peerDependencies": {
  "svelte": "3.x"
},

...
      
      





3.x



, - Svelte, 2 4, ES6 .







, svelte



node_modules



, . NPM 7 .







CDN- . "svelte":...,



package.json



:







    ...
    "module":"dist/clock.mjs",
    "cdn":"dist/clock.min.js",
    "unpkg":"dist/clock.min.js",
    ...
      
      





, CDN . , , Jsdelivr "cdn"



, , . , "unpkg"



.







esbuild



esbuild.js



:







const {build} = require(`esbuild`);
const sveltePlugin = require(`esbuild-svelte`);

//   package.json    pkg
const pkg = require(`./package.json`);

//    Svelte 
const svelte = sveltePlugin({
  compileOptions:{
     //       
    css: true
  }
});

//  IIFE-
build({
  //        package.json
  entryPoints: [pkg.svelte],
  outfile: pkg.cdn,
  format: 'iife',
  bundle: true,
  minify: true,
  sourcemap: true,
  plugins: [svelte],

  //        
  globalName: 'svelteClock',
})

//  ES-
build({
  entryPoints: [pkg.svelte],
  outfile: pkg.module,
  format: 'esm',
  bundle: true,
  minify: true,
  sourcemap: true,
  plugins: [svelte],

  //        
  // dependencies  peerDependencies   package.json
  external: [
    ...Object.keys(pkg.dependencies),
    ...Object.keys(pkg.peerDependencies),
  ]
})
      
      





esbuild .

package.json



"scripts"



esbuild:







  ...
  "scripts": {
    ...
    "build":"node esbuild",
    ...
  }
      
      





:







  npm run build
      
      





dist



sourcemap, , .







Current file structure







Readme.md



README.md



, , . , , , , , , . , . svelte-, . - , . , .









NPM. , , node_modules



. esbuild.js



, . .npmignore



, . β€” esbuild.js



. , .







.Npmignore content







npm run build



, dist



. "scripts"



package.json



:







  ...
  "scripts": {
    ...
    "prepublish":"npm run build",
    ...
  }
      
      





, pacakge.json



:







{
  "name": "svelte-clock-demo",
  "version": "1.0.0",
  "description": "Animated clock component for Svelte",
  "svelte": "components/App.svelte",
  "module":"dist/clock.mjs",
  "cdn":"dist/clock.min.js",
  "unpkg":"dist/clock.min.js",
  "scripts": {
    "build":"node esbuild",
    "prepublish":"npm run build",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Vasya Pupkin",
  "license": "ISC",
  "dependencies": {
    "dayjs": "^1.10.4"
  },
  "devDependencies": {
    "esbuild": "^0.8.43",
    "esbuild-svelte": "^0.4.1",
    "svelte": "^3.32.2"
  },
  "peerDependencies": {
    "svelte": "3.x"
  }
}

      
      





, NPM :







 npm login
 npm publish
      
      





NPM . .









. - :







  npm install --save-dev svelte-clock-demo
      
      





Svelte-, :







<script>
    import Clock from 'svelte-clock-demo';
</script>

<Clock background="white" color="black" />
      
      





, Svelte, ES6 , :







import Clock from 'svelte-clock-demo';

new Clock({
  //   DOM,    
  target: document.getElementById('divForClock'),
  //   
  props:{
    background: 'white',
    color: 'black'
  }
})
      
      





CDN. NPM, CDN , jsdelivr.com.







<html>
  <head>
    <title>  </title>
    <!--    CDN -->
    <script src='https://cdn.jsdelivr.net/npm/svelte-clock-demo'></script>
  </head>
  <body>
    <div id="divForClock"></div>
  </body>
  <script>
    //        esbuild
    new svelteClock.default({
      //   DOM,    
      target: document.getElementById('divForClock'),
      //   
      props:{
        background: 'white',
        color: 'black'
      }
    })
  </script>
</html>
      
      







, - . , UI , Input



,Button



, Checkbox



..







App.svelte



, Sign.svelte



. , , - .







, components



index.js



- , .







export {default as Clock} from './App.svelte';
export {default as Sign} from './Sign.svelte';
      
      





"svelte"



package.json



, index.js



.







  ...
  "svelte":"components/index.js",
  ...
      
      





, :







import {Sign} from 'svelte-clock-demo';
      
      







In the article, we did not touch on the topic of testing, as well as the organization of the development process of the component itself. But you should not neglect them in your projects, because without them it is almost impossible to make a high-quality package with a minimum number of bugs.







If you have any questions about the publication of components, their use, or in general about the Svelte framework, you can always get answers in the Russian-language chat of the Svelte community on Telegram .








All Articles