Webpack Best Practice Series (09)

Source: Internet
Author: User
Tags webp

9. Path-related

It turns out that everything we pack is stored in the Dist directory and not sorted, mess, and we're going to take care of the packaged path to make the packaged directory look more elegant.

9.1. Code Preparation

Let's start by building a directory structure

. ├──node_modules├──src|   ├──assets|       └──css|           └──index.css|       └──img|            └──noding.jpg|       └──js|            └──index.js|   └──index.html├──.babelrc├──package-lock.json├──package.json├──webpack.config.js└──dist

  

You just need to copy the code we wrote earlier, and then delete the contents of dist and create a new assets folder under SRC to install the CSS and IMG.

We enter a piece of code in src/index.html

<! DOCTYPE html>

  

Next, enter the following code in Assets/js/index.js

Introduction of Icon Font import "FONT-AWESOME/CSS/FONT-AWESOME.CSS"//import picture imported imgsrc from '. /img/nodeing.jpg '//Insert the picture into the HTML page document.getElementById ("box"). InnerHTML = '  '

  

Then go to the Webpack.config.js to modify the entry file location

Next, let's test the packaging effect.

NPM Run Dev

  

All of the files are packaged in the Dist directory, and here we have finished the prep work, and then we need to optimize the Webpack configuration so that the packaged files are less cluttered

9.2.webpack configuration 9.2.1. To classify JS files

We want to package the file also like the SRC directory can be categorized storage, first, we put JS into the Assets/js folder, we need to modify the Webpack configuration file, the output directory to get rid of

Output: {    path:path.resolve (__dirname, ' dist/assets '),    filename: ' Js/app.js '},

  

Running NPM run dev to see the effect, found in the Dist directory with a assets file, and has set up the JS folder, App.js also be put in, but, originally packaged out of those files still in, this time, dist directory is more chaotic, we hope each package generated files are up to date, we have to manually remove the last package of files, such as this manual removal dist directory operation, we can hand over to Webpack related plug-in to complete, this plug Piece called Clean-webpack-plugin

Installing the Clean-webpack-plugin Plugin

NPM Install Clean-webpack-plugin--save

  

Modify the Webpack configuration file and introduce the Clean-webpack-plugin plugin

Const PATH = require ("path") const Htmlwebpackplugin = require ("Html-webpack-plugin")//introduced Clean-webpack-plugin plugin const        Cleanwebpackplugin = require ("Clean-webpack-plugin") Module.exports = {entry: "./src/assets/js/index.js", Output: { Path:path.resolve (__dirname, ' dist/assets '), FileName: ' Js/app.js '}, plugins: [New HTMLWEBPA        Ckplugin ({Template: './src/index.html ', filename: ' index.html '}),//Use plug-ins to set directories that need to be purged            New Cleanwebpackplugin ([' Dist '])], Devserver: {open:true}, module: {rules: [ {test:/\.js$/, use:[' Babel-loader '], exclude:path.resolve (__dirname, ' Node_modules ')}, {test:/\.css$/, use: [' Style-loader ', ' Css-loader ' ]},//Process the literal {test:/\.    EOT|SVG|TTF|WOFF|WOFF2) $/, use: ' File-loader '},        {test:/\.                        (jpg|png|gif|webp|bmp) $/, use: [{loader: ' Url-loader ', options: { limit:10240}}]}}}

  

This time you will find that every time you run NPM run Dev, the plugin will first delete the last dist directory, and then create a new dist directory to put the newly packaged files inside

The above steps, we put the JS file in the Assets/js directory, but then, all the files are packaged into the assets directory, We do not want to index.html this file is also packaged into the assets directory, but like in the SRC directory, they should be peer, so we need to modify the path index.html is output

Plugins: [    new Htmlwebpackplugin ({        Template: './src/index.html '),        //This means to go back a layer of        filename: '. /index.html '    }),    new Cleanwebpackplugin ([' Dist ']),

  

9.2.2. Classifying font files

Modify the Webpack configuration file to add an output rule to the font file

Working with the literal {    test:/\. EOT|SVG|TTF|WOFF|WOFF2) $/, use    : [{        loader: "File-loader",        options: {            name: ' Fonts/[name]_[hash:4] . [Ext] '}}    ]},

  

where [name], [hash], [ext] are mutable, name indicates the original file name, hash represents the generated hash value, Hash:4 represents the number of bits that can qualify the hash string, ext indicates the extension of the original file (file suffix)

9.2.3. Classifying picture files

Modify the Webpack configuration file to add an output rule to the picture file

{    test:/\. (jpg|png|gif|webp|bmp) $/, use    : [{        loader: ' Url-loader ',        options: {            limit:10240,            name: ' img/[ Name]_[hash:4]. [Ext] '}}    ]}

  

Because, Ulr-loader is the encapsulation of the File-loader, in which [name], [hash], [ext] means the meaning and the meaning of the file-loader is the same

9.2.4. Classifying CSS Files

CSS files are packaged into the JS file, if you need to package it separately, you need to install another plug-in, Extract-text-webpack-plugin

NPM Install Extract-text-webpack-plugin--save-dev

  

The use of this plugin is similar to other plugin, the first need to introduce plug-ins

Const EXTRACTTEXTWEBPACKPLUGIN = require ("Extract-text-webpack-plugin")

  

Second, you need to instantiate the object, pass in the configuration item, and then add the instantiated object to the plugins option

Const EXTRACTCSS = new Extracttextwebpackplugin ({    //package Output path    filename:  ' assets/css/index.css '}) Plugins: [        New Htmlwebpackplugin ({            Template: './src/index.html ',            filename: './index.html '        }),        new Cleanwebpackplugin ([' Dist ']),        //Here is the object previously instantiated        Extractcss    ],

  

Finally, you need to modify the CSS output rules

{    test:/\.css$/,    use:extractcss.extract ({        fallback: ' Style-loader ',        use:[' Css-loader ')    })},

  

9.2.5. Fix URL Address

When we classify various types of files, run packaged index.html, find the picture, font, CSS and other paths are not correct, no way to work properly, this time, we need to use the output configuration under the Publicpath to fix

Output: {        path:path.resolve (__dirname, ' dist/assets '),        filename: ' js/app.js ',        publicpath: ' assets/'    },

  

Where Publicpath sets the base directory for all static resources, to quickly understand it, you can remember the following formula

静态资源最终访问路径 = output.publicPath + 资源loader或插件等配置路径

For example, the paths we set in various loader are as follows:

CSS Output path name: ' Css/[name]_[hash:4]. [ext] '//Picture Output path name: ' Img/[name]_[hash:4]. [ext] '//font file output path name: ' Fonts/[name]_[hash:4]. [ext] '//JS file output path filename: ' Js/app.js '

  

The Publicpath is set to "assets/", then the final access path is the path of the Publicpath/loader setting, and the sample path will be Assets/img/[name]_[hash:4]. [ext]

In summary, the final URL access path is the Publicpath+loader path.

Next, our NPM start launches our project and finds that the final access is the root directory of the project, Instead of visiting the packaged index.html file, before we find out why we didn't have access to the index.html file, let's start by figuring out some of the most confusing path problems in Webpack.

1.output.path

2.output.publicpath

3.devserver.publicpath

4.devserver.contentbase

Output.path is the output directory for static resources, and the packaged resources are placed here

Output.publicpath is the base directory of static resources, after the directory is set, the final static resource access path will be stitched up in front of this option setting value, it is also convenient for us to set the static resource server address, for example: static resource server address is/HTTP Static.nodeing.com, set this value, the address of the final access image will be http://static.nodeing.com/assets/img/nodeing.com this form, therefore, This is also output.publicpath this option and the latter devserver.publicpath than the larger difference, the former is can be set HTTP URL

Devserver.publicpath This option is the access path to the Webpack-dev-server server, and we know that when the webpack-dev-server is started, the resources are packaged into memory, and you don't have to focus on where it is in memory, and you can understand that the packaged resources are also lost. Out, just output into memory, you can not see it on the hard disk, but it provides an address for us to access, Devserver.publicpath is used to set access to the memory is packaged in the resource address, for example:

Output: {        path:path.resolve (__dirname, ' dist/assets '),        filename: ' js/app.js ',    },devserver: {        open: True,         publicpath: '/aa '    },    other configuration omitted ...

  

Like the above configuration, when the server starts, if you want to access the in-memory app.js, you need to pass Http://localhost:8080/aa/js/app.js

Back to the beginning of the problem, NPM start starts the server and cannot access the packaged index.html? Let's find out the specific reasons for the problems of several paths

The current full webpack configuration is this:

Const PATH = require ("path") const Htmlwebpackplugin = require ("Html-webpack-plugin") const Cleanwebpackplugin = require ( "Clean-webpack-plugin") Module.exports = {entry: "./src/assets/js/index.js", Output: {path:path.resolve (__d Irname, ' dist/assets '), FileName: ' Js/app.js ', Publicpath: ' assets/'}, plugins: [New HTMLWEBP Ackplugin ({Template: './src/index.html ', filename: '. /index.html '}), New Cleanwebpackplugin ([' Dist ']), Devserver: {open:true, CONTAINTB                ASE: ' src/' publicpath: '/AA '}, module: {rules: [{test:/\.js$/,                use:[' Babel-loader ', Exclude:path.resolve (__dirname, ' Node_modules ')}, {                        Test:/\.css$/, use: [' Style-loader ', {        Loader: ' Css-loader ', options: {                    Name: ' Css/[name]_[hash:4].                [Ext] '}}]},//working with text { Test:/\.                         (EOT|SVG|TTF|WOFF|WOFF2) $/, use: [{loader: "File-loader", Options: { Name: ' Fonts/[name]_[hash:4]. [Ext] '}}]}, {test:/\. (                        jpg|png|gif|webp|bmp) $/, use: [{loader: ' Url-loader ', options: { limit:10240, Name: ' Img/[name]. [Ext] '}}]}}}

  

Let's read a few key configurations:

1.path:path.resolve (__dirname, ' dist/assets '), this configuration is the directory of the resource output after packaging, the same when the Webpack-dev-server boot, the resources will be packaged into memory, In a less rigorous but popular word, you can assume that all files are packaged into this directory, except that the directory is placed in memory instead of output to the hard disk, and you access the files in this directory when the path and package to the hard disk are seen as the path, for example: on the hard disk Dist/assets/js/app.js , which is also accessed through this directory structure in memory.

2.publicPath: ' assets/', this configuration, the front we also talked about, is the static resources of the basic path, you can go back to read a bit

3.publicPath: '/aa ', this configuration is the virtual path of the server to access the memory, HTTP://LOCALHOST:8080/AA this address, You can think of the map to the Output.path settings directory, less rigorous but popular, you can think http://localhost:8080/aa this address point to this directory (dist/assets/), then you are in HTTP. Localhost:8080/aa back plus/js/app.js is equivalent to access dist/assets/js/app.js, so after booting through http://localhost:8080/aa/js/ App.js is able to access this JS file

4.filename: '. /index.html ', this configuration in Htmlwepackplugin, sets the HTML location to be packaged. /indicates a return to the previous layer, which means that the structure that is ultimately packaged is this:

├──dist|   ├──assets|       ├──css|       ├──img|       ├──js|   ├──index.html|

  

We can access the Dist/assets directory through HTTP://LOCALHOST:8080/AA, or we can access the deeper files in the directory, just add the file path after HTTP://LOCALHOST:8080/AA. But can never go back to the top directory to access the index.html

When the index.html file is not accessed in memory, Webpack-dev-server will go to the local path, the local path is containtbase: ' src/' This option is set, so when NPM start, Directly open is the SRC directory under the project

OK, the cause of the problem has been found out, next we need to modify the following webpack configuration, the specific idea is

1. 输出目录往上挪动一层    output.path 设置成 path.resolve(__dirname, ‘dist‘),2. 在每个loader上加深一层  js加深一层是这样的 assets/js/app.js  图片加深一层是这样的  assets/img/...,其他,同理3. ../index.html 改为当前目录  ./index.html4. output.publicPath的值设置来和devServer.publickPath的值一样,不然静态资源的访问地址会出错,返回404

In doing so, the original packaged output directory becomes the Dist directory, not the original dist/assets directory, then http://localhost:8080/aa this address point to the memory virtual directory is the Dist directory, then through HTTP/ Localhost:8080/aa/index.html will be able to access the content.

The specific complete configuration is as follows:

Const PATH = require ("path") const Htmlwebpackplugin = require ("Html-webpack-plugin") const Cleanwebpackplugin = require ( "Clean-webpack-plugin") Module.exports = {entry: "./src/assets/js/index.js", Output: {path:path.resolve (__d Irname, ' dist '), filename: ' Assets/js/app.js ', Publicpath: '/aa/'}, plugins: [New Htmlwebpack Plugin ({Template: './src/index.html ', filename: './index.html '}), new CLEANWEBPACKPL            Ugin ([' Dist '])], Devserver: {open:true, Publicpath: '/aa '}, module: {rules: [  {test:/\.js$/, use:[' Babel-loader '], Exclude:path.resolve (__dirname, ' Node_modules ')}, {test:/\.css$/, use: [' style                            -loader ', {loader: ' Css-loader ', options: { Name: ' AssetS/css/[name]_[hash:4].                [Ext] '}}]},//working with text { Test:/\.                         (EOT|SVG|TTF|WOFF|WOFF2) $/, use: [{loader: "File-loader", Options: { Name: ' Assets/fonts/[name]_[hash:4]. [Ext] '}}]}, {test:/\. (                        jpg|png|gif|webp|bmp) $/, use: [{loader: ' Url-loader ', options: { limit:10240, Name: ' Assets/img/[name]. [Ext] '}}]}}}

  

Usually Output.publicpath and Devserver.publicpath set to "/", so that we can go through the http://localhost:8080/to access the packaged index file, self-modification, try the effect it!!

Webpack Best Practice Series (09)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.