As the mainstream construction tool at present, WebPack has to plan a considerable amount of time for debugging before each development due to its rapid version iteration and complex configuration mode. The entire environment setup process will be recorded here to provide basic ideas for beginners.
Just like when I was developing Vue-Sitemap, the build tool often needs to meet the following requirements:
- Build code that generates CommonJS/UMD/ES Modules for the user
- Tests need to be run and progress of test coverage checked
- Use VS Code editor for breakpoint debugging during development
The above three are the basic requirements for developing a package. Of course, there are more details to be added, but I will add them in another article because it is too long. (Readers are welcome to comment on the features you think are needed (• ̀ω•́)✧)
Step 1: Build the tools
We’ll start with the basics. We’ll need to install Node.js(10.x) as the environment to run all of our code, as well as WebPack.
Initialize the project
Since I need to publish the project to NPM, use the command to initialize the project description file package.json
npm init
Copy the code
For the first time the details of each reader to find other articles to fill it, here is not detailed
Now look at the directory structure
│ ├─ SRC // Source directory │ ├─ js // Import file ├─tests // Test code directory │ ├─dist ├ ─ garbage // ├ ─ garbage //Copy the code
Add webpack
npm install -D webpack webpack-cli cross-env
//or
//yarn add webpack webpack-cli cross-env -D
Copy the code
Webpack V4 is used here, and subsequent Settings are also based on 4. Cross-env is a package to help normal use of environment variables in Win, which I developed in Win and added here.
Yarn is a fast, reliable, and secure dependency management tool. If you find NPM slow to install, try it.
After the dependency download is resolved, use the package.json setup build command after it is convenient.
//# package.json
{
//...
"scripts": {
"build": "cross-env NODE_ENV=production webpack --propress --hide-modules",
}
}
Copy the code
Here we can run the command NPM run build to see if the build succeeds. If it succeeds, the main. Js file will be generated in the dist directory.
Configuration webpack
Create the webpack.config.js file to configure webpack. To satisfy our first need, generate code for three patterns:
//# webpack.config.js
const package = require('./package.json')
const path = require('path')
const config = {
entry: "./src/index.js".// Import file
output: { // Output Settings
path: path.resolve(__dirname, "./dist"),
filename: `${package.name}.js`
},
resolve: {
alias: {
"@": path.resolve(__dirname, "./src")}}}if (process.env.NODE_ENV === "umd") {
config.optimization = { minimize: false };
config.output.library = package.name;
config.output.libraryTarget = "umd2";
config.output.filename = `${package.name}.js`;
}
if (process.env.NODE_ENV === "umd:min") {
config.output.library = package.name;
config.output.libraryTarget = 'umd2';
config.output.filename = `${package.name}.min.js`;
}
if (process.env.NODE_ENV === "es") {
config.output.library = package.name;
config.output.libraryTarget = "amd";
config.output.filename = `${package.name}.es.js`;
}
if (process.env.NODE_ENV === "commonjs") {
config.output.library = package.name;
config.output.libraryTarget = "commonjs2";
config.output.filename = `${package.name}.common.js`;
}
module.exports = config
Copy the code
Adding build commands
Add a new run command for package.json
//# package.json {"version": "0.1.0", "name": "vscode-mocha-webpack-example", "description": / SRC /index.js", "scripts": {"build": {"build": "npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:umd:min", "build:umd": "cross-env NODE_ENV=umd webpack --mode=production --progress --hide-modules", "build:umd:min": "cross-env NODE_ENV=umd:min webpack --mode=production --progress --hide-modules", "build:es": "cross-env NODE_ENV=es webpack --mode=production --progress --hide-modules", "build:commonjs": "cross-env NODE_ENV=commonjs webpack --mode=production --progress --hide-modules" } ... }Copy the code
Run NPM run build to generate files in CommonJS/UMD/ES Modules.
Something like this:
├─dist │ vscode-mocha-webPack-example.common.js │ vscode-mocha-webpack-example.es.js │ ├─dist │ vscode-mocha-webpack-example.es.js │ Vscode - mocha - webpack - example. Min. Js │ vscode mocha - webpack - example. JsCopy the code
Specifies the terminal
In order for your build files to be part of the final release package, you must declare them. Add the following to package.json:
"main": "dist/vscode-mocha-webpack-example.common.js",
"module": "dist/vscode-mocha-webpack-example.es.js",
"jsnext:main": "dist/vscode-mocha-webpack-example.es.js",
"files": [
"dist",
"src"
],
Copy the code
files
The section tells NPM to package these folders at release time (otherwise, they will be ignored because they are listed in.gitignore
File)main
Define the CommonJS build terminaljsnext:main
andmodule
Defines terminals for ES2015 builds (we defined two terminals becausejsnext:main
Is the earliest specification in use, whilemodule
Is more consistent with standard specifications).
Second, set up Babel
Babel allows us to use the latest syntax without having to worry about the runtime not supporting it. Use babel-loader to import Babel support in webpack, and use babel-preset-env for the latest compatibility Settings:
npm install -D babel babel-cli babel-preset-env
//or
//yarn add babel babel-cli babel-preset-env -D
Copy the code
Create the Babel configuration file
Then set the babel-compatible rules in the.babelrc file:
{
"presets": [["env",
{
"useBuiltIns": false."modules": false}}]]Copy the code
Add babel-loader to Webpack
When we write JavaScript using the latest syntax, Webpack matches the processing of all JS files to Babel.
const package = require('./package.json')
const path = require('path')
const config = {
entry: "./src/index.js".output: {
path: path.resolve(__dirname, "./dist"),
filename: `${package.name}.js`
},
resolve: {
alias: {
"@": path.resolve(__dirname, "./src")}},module: {
rules: [{test: /\.js$/.loader: 'babel-loader'.exclude: /node_modules/}]}}... module.exports = configCopy the code
When you run the build, WebPack loads Babel and its associated Settings to transform and generate the code, and by this point, the building-related Settings are almost complete.
Third, add automated tests
For those of you who are familiar with automated testing, you should be familiar with Mocha. Simple tests are handled using Mocha, assertion library CHAI, and chai-as-promised, which provide promise support. Install these dependencies first:
npm install -D mocha mocha-webpack chai chai-as-promised
//or
//yarn add mocha mocha-webpack chai chai-as-promised -D
Copy the code
Mocha-webpack is a plugin for testing code that wants to use new ES features.
Then add the test command to package.json:
{
//...
"scripts": {
"build": "npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:umd:min",
"build:umd": "cross-env NODE_ENV=umd webpack --mode=production --progress --hide-modules",
"build:umd:min": "cross-env NODE_ENV=umd:min webpack --mode=production --progress --hide-modules",
"build:es": "cross-env NODE_ENV=es webpack --mode=production --progress --hide-modules",
"test": "cross-env NODE_ENV=test mocha-webpack tests/**/*.spec.js"
}
//...
}
Copy the code
.babelrc also needs to be set:
{
//...
"env": {
"test": {
"presets": [
[
"env",
{
"modules": false,
"targets": {
"node": "current"
}
}
]
]
}
}
}
Copy the code
Add tests to test/unit/example. Spec. Js and SRC/index. The js two files, the code is as follows:
├─ SRC │ ├─ exercises ├─ unit example.specCopy the code
//# src/index.js
export function getRole(user){
switch(user){
case "Packy":
return "admin"
case "Joan":
return "reader"}}//# tests/unit/example.spec.js
import { assert } from "chai";
import { getRole } from "@/index";
describe('Testing', ()=>{
it('Packy is admin', () => { assert.equal(getRole('Packy'), 'admin') })
it("Joan is reader", () => { assert.equal(getRole("Joan"), "reader")}); })Copy the code
Now run the test command to get the test result:
npm run test
Copy the code
The output might look something like this:
WEBPACK Compiling...
[======================= ] 91% (additional chunk assets processing)
WEBPACK Compiled successfully in 5893ms
MOCHA Testing...
Testing
√ Packy is admin
√ Joan is reader
2 passing (39ms)
MOCHA Tests completed successfully
Copy the code
Questions about test coverage
With tests, you also need to know if the tests cover all the code (I’ve heard it’s up to 80%, but some teams may require more than 90-95%). How do you know?
The nyc package will help me check test coverage by installing dependencies first:
npm install -D nyc babel-plugin-istanbul
Copy the code
Then set the check scope and add commands:
//# package.json
{
...
"scripts": {
"build": "npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:umd:min",
"build:umd": "cross-env NODE_ENV=umd webpack --mode=production --progress --hide-modules",
"build:umd:min": "cross-env NODE_ENV=umd:min webpack --mode=production --progress --hide-modules",
"build:es": "cross-env NODE_ENV=es webpack --mode=production --progress --hide-modules",
"build:commonjs": "cross-env NODE_ENV=commonjs webpack --mode=production --progress --hide-modules",
"test": "cross-env NODE_ENV=test nyc mocha-webpack tests/**/*.spec.js"
},
...
"nyc": {
"include": [
"src/**"
],
"instrument": false,
"sourceMap": false
}
...
}
Copy the code
You can also see that Babel also needs to add related Settings:
//# .babelrc
{
...
"env": {
"test": {
"presets": [
[
"env",
{
"modules": false,
"targets": {
"node": "current"
}
}
]
],
"plugins": [
"istanbul"
]
}
}
}
Copy the code
Running NPM run test yields the following:
WEBPACK Compiling...
[======================= ] 91% (additional chunk assets processing)
WEBPACK Compiled successfully in 5893ms
MOCHA Testing...
Testing
√ Packy is admin
√ Joan is reader
2 passing (39ms)
MOCHA Tests completed successfully
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.js | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Copy the code
Here’s what these four columns mean:
- Stmts :
Statement coverage
Declare coverage. Is every statement in the program executed? - Branch:
Branch coverage
Branch coverage, is every branch (also known as DD path) of every control structure executed (such as if and case statements)? For example, given an if statement, have true and false branches been executed? - Funcs:
Function coverage
Method coverage, is every function (or subroutine) in the program called? - Lines:
Line coverage
Line code coverage, has every executable line in the source file been executed?
The number of lines of code that are not covered will be shown in the Jude Line column.
Provide async/await support for tests
To use async/await syntax in your tests, add the setup.js file and add babel-polyfill at the entry:
require("babel-polyfill");
Copy the code
And change useBuiltIns to Entry in. Babelrc:
{... "env": { "test": { "presets": [ [ "env", { "useBuiltIns": "entry", "modules": false, "targets": { "node": "current" } } ] ], "plugins": [ "istanbul" ] } } }Copy the code
Add new code to SRC /index.js and tests/example.spec.js:
//# src/index.js
export function getUsers(){
return new Promise((resolve, reject) = >{
setTimeout((a)= >{
console.log('123')
resolve(['Packy'.'Joan'])},1000)})}//# tests/unit/example.spec.js
describe('GetUsers', ()=>{
it('get result is Array'.async() = > {const users = await getUsers();
assert.isArray(users, "[message]"); })})Copy the code
Run the test to see the results!
Take testing a step further and debug in VS Code
To debug VS Code breakpoints you need to add some extra Settings, add the following Code to webpack.config.js.
//# webpack.config.js
/ /...
if (process.env.NODE_ENV === "test") {
config.devtool = "eval-source-map";
config.output = Object.assign(config.output, {
devtoolModuleFilenameTemplate: "[absolute-resource-path]".devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]? [hash]'
});
}
module.exports = config;
Copy the code
Add debug Code in VS Code
Open the VS Code Debug panel and select Add Configuration from the drop down option (or create and open the.vscode/launch.json file directly) :
// Use IntelliSense to learn about related attributes. // Hover to view descriptions of existing properties. / / for more information, please visit: https://go.microsoft.com/fwlink/?linkid=830387 {" version ":" 0.2.0, "" configurations: [{" type" : "node", "request": "launch", "name": "Mocha-webpack Tests", "program": "${workspaceFolder}/node_modules/mocha-webpack/bin/mocha-webpack", "args": [ "--full-trace", "--timeout", "999999", "--colors", "tests/**/*.js" ], "sourceMaps": true, "env": { "NODE_ENV": "test" }, "internalConsoleOptions": "openOnSessionStart" }] }Copy the code
The breakpoint effect can be obtained from the source code in the SRC directory or from the tests directory. If you want to try it out, download vscode-mocha-webpack-example and install the dependency.
The setting reference is from vscode-ts-webpack-node-debug-example
It is worth noting that devTool does not have breakpoints with eval Settings, but it does not have breakpoints with mocha-Webpack debugging. After my company friends and I searched for the issue of vscode and mocha-webpack many times, After various attempts, it was found that eval-source-map worked best for breakpoints. (Eval also worked, but the breakpoint sourcemap was more or less offset at breakpoints because the source was the generated file.)
д ´*)9 ┴┴. To solve this problem, please download the latest version of NVM v1.1.7.
Finally:
My motivation comes from your fingers, please use your fingers hard to give me a thumbs-up! D (´ omega `)
Don’t forget to click favorites φ(>ω<*) oh!
At the same time, welcome all novices and gods to leave a comment at the bottom of this article. Thank you for participating in the discussion! ✧ (, ̀ omega, ́)
The following is a complete example of this article, remember star!
- vscode-mocha-webpack-example
And a big thanks to Mather co-editor!