A thought about migrating Codepen locally

This is my codepen above written backgammon migrated to the local, with webpack some thoughts, you can go to play, by the way, I have a look at how to configure my webpack, and this backgammon how to write.

You can read this article while referring to the source code on Github.

Making the source code

Codepen demo (github)

Why do we migrate locally

As anyone who’s used Codepen knows,codepenIs a very easy to use, web demo quick writing tool. All you need to do is write your page on the left, and then preview it in real time on the right. For example:

It also provides many HTML, CSS, and HTML preprocessing tools. For example, HTML has PUG, EJS and so on; The CSS includes SCSS, SASS, and LESS. Javascript has Babel, Typescript, coffeescript, and so on. It’s true that we can get our demo development done quickly on the web, but what if Codepen doesn’t meet some of your needs? In Codepen, there are no code smart tips, no quick code formatting tool, and error tips are useless if something goes wrong. At this point, we may need to set up a local project and move our demo to local development.

Thinking of Migration Scheme

If you know how to use HTML, CSS, and Javascript to write small demos in Codepen, it is very easy to build local projects. You just need to create a new folder, copy and paste the codepen HTML and other text, and then modify the links. But what if you use a compiler like PUG, SCSS, typescript, etc? You might be thinking, why don’t I just start a new NPM project, compile PUG, SCSS, typescript into HTML files, and link them in HTML? This approach seems to work, but in practice it turns out to be very inefficient. Because every time you change a file, you have to manually compile it and see it in the browser, which is a far cry from the Codepen experience. Then you may think, at this time, our requirement is to modify the file and then automatically compile it. Then we can use Nodemon to monitor the source file and compile it separately after each operation. This is fine in theory, but only for beginners. In real projects, the source files are so large that a full compilation is required every time a small part of the file is changed, and the waiting time can be unbearable.

Right way

In fact, there is a mature solution for front-end resource packaging, which is Webpack.

Essentially, WebPack is a static module packaging tool for modern JavaScript applications. When WebPack works with an application, it internally builds a dependency graph that maps to each module required for the project and generates one or more bundles.

As I write this, WebPack is version 5.6.0, and the following is based on version 5.6.0.

Webpack, since Webpack 4, has made it possible to get started quickly without configuration, which has greatly reduced the freshman difficulty of getting started. As you can see above, WebPack compiles all the weird dependencies into files that browsers can understand and run directly. But it’s not webPack that compiles the files on the left of the image above and combines them in some magical way, it’s WebPack’s loader that does the work.

loader

Loader is used to convert the module source code. Loader allows you to preprocess files when importing or “loading” modules. As such, Loader is similar to “tasks” in other build tools and provides a powerful way to handle the front-end build steps. Loader can convert files from different languages (such as TypeScript) to JavaScript or convert inline images to data urls. Loader even allows you to import CSS files directly into JavaScript modules!

For example, you need to process puG, SCSS and TS files. Webpack does not provide the ability to compile the above files, but calls the corresponding preprocessing tools through loader. Therefore, it is necessary to install the corresponding preprocessing tools, such as PUG and SASS. In typescript, you also need to install corresponding loaders, such as pug-loader, Sas-loader, and TS-loader.

module: {
    rules: [{test: /\.pug$/,
        include: path.resolve(__dirname, 'src'),
        use: 'pug-loader'
      },
      {
        test: /\.ts$/,
        include: path.resolve(__dirname, 'src'),
        use: "ts-loader"
      },
      {
        test: /\.scss$/i,
        include: path.resolve(__dirname, 'src'),
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader"."sass-loader"]]}}Copy the code

plugin

Plug-ins are the backbone of WebPack. Webpack itself is built on top of the same plugin system you use in your WebPack configuration!

Plug-ins are designed to solve other things that loader cannot implement.

Loader provides the ability to combine with pre-processing software, but with plug-ins we can do things that are not possible. Webpack, for example, packs CSS in js files by default, but if you want to pull CSS out separately, put it in the HTML head and put js under the body. At this time we need to take advantage of the MiniCssExtractPlugin capabilities; Or we need to clean up the dist directory with every build, we need to leverage the capabilities of the CleanWebpackPlugin, and so on.

plugins: [
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash].css"
    }),
    new HtmlWebpackPlugin({
      template: "./src/index.pug".inject: true})]Copy the code

Configuration vs None

All the configuration we go to Github to see, do not paste over the length.

In my latest code submission, I have split the development mode and production mode into two different configuration files. The same part is put in webpack.common.js. You can refer to this file directly.

We said earlier that WebPack runs without configuration, but that doesn’t mean we don’t need to configure it at all. Flexibility and simplicity of configuration are always trade-offs. If our Webpack, instead of declaring what loader and plugin we need to use through a configuration file, sniffed package.json and loaded itself with the default configuration, we would be in a state of panic. Let’s configure our Webpack next.

Webpack uses webpack.config.js as the configuration entry point by default, but you can also use the -c option to explicitly declare the configuration file you want to use. For example, if we need to separate development mode from production mode, we need to load different configurations.

Thinking after you’ve done it

With the above configuration, we now have an environment where we can copy the content from Codepen and run it directly. But if next time we use CSS preprocessors instead of SCSS, we use less; What if we use EJS instead of PUG for the HTML template? Should we create a new WebPack project and install different loaders and write different configuration files? Or copy the old configuration file and change it again? It’s a bit of a bad taste.

specification

I have not implemented hahaha, just have this idea, I will write another article when I achieve it.

Instead of creating a project without specification and without complexity, abstract out the same parts of it. Build a CLI for your own team, and bootstrap the corresponding project each time you build a project. After writing this, we can understand that the reason why we need infrastructure is not KPI-oriented, but that such a design can achieve a goal in a more standardized, simpler and faster way, which can simplify our work.

conclusion

If you’re stuck and feel like you’re just going to call libraries and use existing tools to develop web pages, think about how you can reduce unnecessary duplication and make the front end more automated and lowcode.