preface
I have been learning the basics of WebPack for a while, but neither the documentation nor the introductory video is as good as what I learned in practice.
Here are a few things I learned while working on the MarkDown-to-HTML plugin (sort of consolidating my webPack primer). (B station front end of The video of Ono Mori, you can check it out if you are interested) including but not limited to:
- Some basic configuration of WebPack
- Some regular expression writing
- How do I build a DOM tree
- .
The result is this: The Markdowm on the left renders as the HTML on the right
Instead of thinking about how to get Markdown to HTML, let’s look at how to get started. Let’s release the directory:
- First, you need to build a project with WebPack.
- Create a plugin folder that contains the soul of our plugin
- Since it is MD to HTML then we have a MD document, MY MD document should be transferred to imaging first
<h1>**</h1>
A similar string containing the contents is inserted into the template.html template to output an HTML file
1. Building projects with WebPack (in Retrospect)
- Create a folder for md-to-html-plugin
Use the following command
- npm init -y
- npm install webpack webpack-cli webpack-dev-server -D
Create it in the root directory
- webpack.config.js
- src/app.js
- plugin/md-to-html-plugin/ index.js
- plugin/md-to-html-plugin/ compier.js
<h1>**</h1> </h1>
- plugin/md-to-html-plugin/template.html
The following are introduced in turn:
2. Webpack. Config. Js configuration
Contains:
- Packing entry
- Export output
- Pattern mode
- Plugin MdToHtmlPlugin (our own)
const { resolve } = require('path')
const MdToHtmlPlugin = require('./plugin/md-to-html-plugin')
module.exports = {
mode: 'development'.entry: resolve(__dirname, 'src/app.js'),
output: {
path: resolve(__dirname, 'dist'),
filename:'app.js'
},
plugins: [
new MdToHtmlPlugin({
template: resolve(__dirname, 'text.md'),
filename: 'text.html']}}),Copy the code
3. Md-to-html-plugin/index.js
3.1 Definition of plug-in:
Plug-ins are instantiated from a constructor on which the Prototype object has the apply method. This apply method is called by the WebPack Compiler once when the plug-in is installed. The apply method can receive a reference to the WebPack Compiler object, which can be accessed in a callback function.
3.2 MdToHtmlPlugin infrastructure
const { readFileSync } = require('fs') 1.You need to read the file MD and the templateconst { resolve } = require('path')
const INNER_MARK = '<! -- inner -->' 2.Template.html to hold the transformed HTML tagsconst {compileHTML} = require('./compiler') 3.Md - HTML conversionclass MdToHtmlPlugin { 4.In the WebPack configuration we use thenewThe way to create this side, we set up aclassClass, which takes two arguments,mdThe filename of the document, and the filename of the outputconstructor({ template, filename }) {
5.If the MD file cannot be found, the error is directly guaranteedif(! template) {throw new Error('Template not found')}this.template = template
6.Set the output file name, if there is a file name, if not, set to'md.html'
this.filename = filename ? filename : 'md.html'
}
7.The apply () methodapply(compiler) {
compiler.hooks.emit.tap('md-to-html-plugin'.(compilation) = > {
// I put the whole apply method content below to analyze
8.In this method, we will read the md document, generate a DOM tree, and put it back in template-html})}}module.exports = MdToHtmlPlugin
Copy the code
3.3 the apply () method
- compiler
- compiler.hooks.emit.tap
- Emit: Generate resources before the output directory
- Parameters:
compilation
- compilation
apply(compiler) {
compiler.hooks.emit.tap('md-to-html-plugin'.(compilation) = > {
const _assets = compilation.assets;
const _mdContent = readFileSync(this.template, 'utf8');
const _templateHtml = readFileSync(resolve(__dirname, 'template.html'), 'utf8')
// Convert the md document lines into an array _mdContentArray
const _mdContentArray = _mdContent.split('\n')
// compileHTML constructs this number into a DOM tree _htmlStr
const _htmlStr = compileHTML(_mdContentArray)
// Insert the DOM into template.html
const _finalHTML = _templateHtml.replace(INNER_MARK,_htmlStr)
_assets[this.filename] = {
source() {
return _finalHTML
},
size() {
return _finalHTML.length
}
}
})
}
Copy the code
Website:
A plug-in consists of the following
- A named JavaScript function.
MdToHtmlPlugin
- Define it on its prototype
apply
Methods.apply(compiler)
- Specify one that touches the WebPack itselfEvent hooks.
compiler.hooks.emit.tap
- Manipulate instance-specific data within WebPack.
- The Callback provided by WebPack is called after the functionality is implemented
4. Md-to-html string conversion
4.1 Using JS Objects to create trees
4.1.1 What tree to create:
{
'h1-1626856207419': { type: 'single'.tags: [ ' This is an h1 title \r
']},'ul-1626856207993': {
type: 'wrap'.tags: [
' the first item in this ul list \r '.' the first item in this ul list \r '.' the first item in this ul list \r '.' the first item in this ul list \r ']},'h2-1626856207560': { type: 'single'.tag: [ ' This is an h2 title \r
']},'ol-1626856207336': {
type: 'wrap'.tags: [
'. This is the first item in an ol list \r '.'. This is the first item in an ol list \r '.'. This is the first item in an ol list \r '.'. This is the first item in an ol list ']}}Copy the code
4.1.2 Detailed Steps:
First of all, we passed an array of rows to compileHTML(_mdContentArray) in index.js, hoping that compileHTML would first convert the md array to a DOM tree. Insert the tree into the template.
- Convert the MD array to a DOM tree
There are three kinds of things
# # #
The title class we need to convert to h1 and H2-
Unordered list we need to convert to UL li1. 2.
Ordered list we need to convert to Ol Li
Of course, each tag contains the content we need. input = matched.input
- Use the re to distinguish the cases in this set
const reg_mark = / ^ (. +?) \s/
// Match the beginning of #
const reg_sharp = / # ^ \ /
// Match an unordered list -
const reg_crossbar = / ^ \ - /
// Match ordered list 1. 2.
const reg_number = /^\d/
Copy the code
- One more thing to note
The Li in UL and the Li in OL are put into UL or OL together, so it is necessary to judge whether the opening label of the last time is the same as that of this time
_lastMark === mark
Copy the code
4.1.3 Specific code:
function createTreel(_mdArr) {
let _htmlPool = {}
let _lastMark = ' ' // This is used to determine whether, like the li label, it needs to be put together in ol or ul
let _key = 0
_mdArr.forEach(mdFragment= > {
// console.log(mdFragment)
const matched = mdFragment.match(reg_mark);
if (matched) {
const mark = matched[1]
const input = matched.input
console.log(matched,'matched') // We can see what is printed by matched here
// md-to-html three operations title unordered list ordered list}});return _htmlPool
}
Copy the code
Here’s what Matched printed out
const mark = matched[1] md matches ## # -1.Etc.constInput = matched. Input contentCopy the code
[ The '#'.The '#'.index: 0.input: '# This is a h1 title \r'.groups: undefined ] matched
[ The '-'.The '-'.index: 0.input: '- the first item in this ul list \r'.groups: undefined ] matched
[ The '-'.The '-'.index: 0.input: '- the first item in this ul list \r'.groups: undefined ] matched
[ The '-'.The '-'.index: 0.input: '- the first item in this ul list \r'.groups: undefined ] matched
[ The '-'.The '-'.index: 0.input: '- the first item in this ul list \r'.groups: undefined ] matched
[ '## '.'# #'.index: 0.input: '## this is a h2 title \r'.groups: undefined ] matched
['1..'1..index: 0.input: '1. The first item of this ol list \r'.groups: undefined] matched
['2.'.'2.'.index: 0.input: '2. The first item of this ol list \r'.groups: undefined] matched
['3.'.'3.'.index: 0.input: '3. The first item of this ol list \r'.groups: undefined] matched
[ '4..'4..index: 0.input: '4. This is the first item in an OL list '.groups: undefined ] matched
Copy the code
4.3 Detailed processing of mD-to-HTML strings
4.3.1 Processing the Unique Value of key
function randomNum() {
return new Date().getTime() + parseInt(Math.random() * 1000);
}
module.exports = {
randomNum
}
Copy the code
4.3.2 Processing of headings H1 h2
- First match the title h1.h2…
if (reg_sharp.test(mark)) { // Match #
const tag = `h${mark.length}`; // Convert to h1, H2, etc
const tagContent = input.replace(reg_mark, ' ')
if (_lastMark === mark) {
// If the previous tag is the same as this one, splice it before
_htmlPool[`${tag}-${_key}`].tags = [..._htmlPool[`${tag}-${_key}`].tags,` <${tag}>${tagContent}</${tag}> `]}else {
// Otherwise create a new title tag
_lastMark = mark
_key = randomNum();
_htmlPool[`${tag}-${_key}`] = {
type: 'single'.// A single identifier
tags: [` <${tag}>${tagContent}</${tag}> `]}}}Copy the code
4.3.3 Processing unordered Lists
if (reg_crossbar.test(mark)) {
// console.log(matched)
const tagContent = input.replace(reg_mark, ' ');
const tag = 'li';
if (reg_crossbar.test(_lastMark)) {
_htmlPool[`ul-${_key}`].tags = [..._htmlPool[`ul-${_key}`].tags ,` <${tag}>${tagContent}</${tag}> `]}else {
_lastMark = mark
_key = randomNum();
_htmlPool[`ul-${_key}`] = {
type: 'wrap'.// Multiple identifiers
tags: [` <${tag}>${tagContent}</${tag}> `]}}}Copy the code
4.3.4 Processing ordered lists
if (reg_number.test(mark)) {
const tagContent = input.replace(reg_number, ' ')
const tag = 'li'
if (reg_number.test(_lastMark)) {
_htmlPool[`ol-${_key}`].tags = [..._htmlPool[`ol-${_key}`].tags ,` <${tag}>${tagContent}</${tag}> `]}else {
_lastMark = mark;
_key = randomNum();
_htmlPool[`ol-${_key}`] = {
type: 'wrap'.tags: [` <${tag}>${tagContent}</${tag}> `]}}}Copy the code
4.4 Template Compilation
function compileHTML(_mdContentArray) {
const _htmlPool = createTreel(_mdContentArray)
// sconsole.log(_htmlPool)
let _htmlStr = ' '
let item
for (let k in _htmlPool) {
// console.log(k, _htmlPool[k])
item = _htmlPool[k]
if (item.type === 'single') {
// A single title tag
item.tags.forEach((tag) = >{ _htmlStr += tag; })}else if (item.type === 'wrap') {
// Multiple tag lists
console.log(item.tags,'2')
let _list = ` <${k.split(The '-') [0]}> `
item.tags.forEach((tag) = > {
_list += tag;
})
_list += ` < /${k.split(The '-') [0]}> `
_htmlStr += _list
}
}
return _htmlStr
}
module.exports = {
compileHTML
}
Copy the code
5. Compile the template
There’s a comment in the body
<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta Name ="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <body> <! -- inner --> </body> </html>Copy the code
Reference documents:
1. The webpack compiler hook
2. Video
There are many places will not not understand, continue to learn…