赞
踩
目录
二十五、webpack中path、outputPath、publicPath联系与区别
- npm i webpack@4.41.2 webpack-cli@3.3.10 -g //全局安装,作为指令使用
- npm i webpack@4.41.2 webpack-cli@3.3.10 -D //本地安装,作为本地依赖使用
注意:如果是局部安装,则需要在package.json中配置scripts,通过运行"npm run start"或"npm start"运行webpack:
- {
- "scripts": {
- "start": "webpack"
- }
- }
开发配置指令:
webpack src/js/index.js -o dist/js/index.js --mode=development
生产配置指令:
webpack src/js/index.js -o dist/js/index.js --mode=production
可在package.json中配置scripts,通过运行"npm run build"运行webpack:
- "scripts": {
- "build": "webpack src/js/index.js -o dist/js/index.js --mode=production"
- }
webpack.config.js:
- /**
- * 此文件是webpack配置文件,用于指定webpack去执行哪些任务
- */
-
- const path = require('path');
-
- module.exports = {
- entry: './src/js/index.js', // 由cmd执行目录决定
- output: {
- path: path.resolve(__dirname, 'dist/js'), // 由当前文件所在位置和要生成的dist位置关系决定
- filename: 'bundle.js'
- },
- mode: 'development',
- devtool: 'inline-source-map'
- };
配置好上述文件后在cmd中通过:
webpack
命令即可运行
假如webpack配置文件为“./config/webpack.base.config.js”,则package.json中打包命令配置为:
- "scripts": {
- "build": "webpack --config ./config/webpack.base.config.js"
- }
概述:webpack不能直接解析less文件,需要借助loader编译解析。
1、安装loader:
npm i style-loader@2.0.0 css-loader@4.3.0 less-loader@7.0.1 less@3.12.2 -D
less-loader基于less,所以要安装less。
注意各包的版本,否则会报错。
package.json:
- {
- "name": "webpack4",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "css-loader": "^4.3.0",
- "less": "^3.12.2",
- "less-loader": "^7.0.1",
- "style-loader": "^2.0.0",
- "webpack": "^4.41.2",
- "webpack-cli": "^3.3.10"
- }
- }
2、配置loader:
- /**
- * 此文件是webpack配置文件,用于指定webpack去执行哪些任务
- */
-
- const path = require('path');
-
- module.exports = {
- entry: './src/js/index.js', // 由cmd执行目录决定
- output: {
- path: path.resolve(__dirname, 'dist/js'), // 由当前文件所在位置和要生成的dist位置关系决定
- filename: 'bundle.js'
- },
- mode: 'production',
- //1、所有的loader都要添加在module对象的rules中
- //2、rules是一个数组,数组中的每一个对象就是一个loader
- //3、loader特点:下载后无需引入,只需申明
- module: {
- rules: [{
- test: /\.less$/, //匹配所有less文件
- use: [
- 'style-loader', //3、用于在html文档中创建一个style标签,将样式“塞”进去
- 'css-loader', //2、将less编译后的css转换为CommonJs的一个模块
- 'less-loader' //1、将less编译成为css,但不生成单独的css文件,在内存中
- ]
- }]
- }
- };
3、运行指令:webpack
附:
src/css/demo.less:
- .demo1{
- width: 500px;
- height: 500px;
- background: #FF0000;
- }
- .demo2{
- width: 200px;
- height: 200px;
- background: #000000;
- }
src/js/index.js:
- import func1 from './moudle1'
- import func2 from './moudle2'
- import '../css/demo.less'
-
- console.log(func1(1, 2));
- console.log(func2(2, 3));
- console.log("webpack!");
index.html:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
- <body>
- <div class='demo1'></div>
- <div class='demo2'></div>
- <script src="./dist/js/bundle.js"></script>
- </body>
- </html>
高版本的火狐、chrome等标准浏览器直接支持es6中const和箭头函数等一般语法及promise等高级语法,但低版本的火狐、chrome等标准浏览器及ie不行,使用babel-loader可以将一般es6语法转换成es5语法。
安装loader:
npm i babel-loader@8.1.0 @babel/core@7.11.6 @babel/preset-env@7.11.5 -D
babel-loader:与 Webpack 协同工作的模块,加载处理 js 文件;
@babel/core:Babel 编译器的核心模块,是 babel-loader 依赖;
@babel/preset-env:Babel 预置器,用于分析 ES6 语法;
配置loader:
- module: {
- rules: [{
- test: /\.m?js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-env']
- }
- }
- }]
- }
我们在 src 中的 js 文件,使用 ES6 的箭头函数来尝试一下;
- let fn = (x, y) => x + y;
- console.log(fn(10, 20));
PS:在没有使用 Babel 时,它打包会原封不动的使用 ES6 语法;
PS:在使用 Babel 之后,编译后的代码如下:
- var fn = function fn(x, y) {
- return x + y;
- };
-
- console.log(fn(10, 20));
如果你使用了未纳入标准(提案中)的代码,打包时,它会提醒你安装相关插件:
- //提案中,尚未纳入标准的语法
- class Person {
- #name;
- constructor() {
- this.#name = 'Mr.Lee';
- }
- }
安装相关插件:
npm i @babel/plugin-proposal-class-properties -D
- options: {
- presets : [
- '@babel/preset-env'
- ],
- plugins : [
- '@babel/plugin-proposal-class-properties'
- ]
- }
高版本的火狐、chrome等标准浏览器直接支持es6中const和箭头函数等一般语法及promise等高级语法,但低版本的火狐、chrome等标准浏览器及ie不行,使用polyfill或core.js可以将所有es6语法转换成es5语法,使得其兼容性更强(包括兼容ie)。
1、使用polyfill
安装polyfill:
cnpm i @babel/polyfill@7.12.1 -D
使用:
入口文件中直接引入:
import '@babel/polyfill'
- /**
- * 当前文件是入口文件,可汇总js、css、字体、图片、音频、视频
- */
- import '@babel/polyfill' //包括es6高级语法的转换,不管编码人员使用了哪些新语法,全部新语法都转换
- import module1 from './module1'
- import module2 from './module2'
- import module3 from './module3'
- import '../css/demo.less'
-
- module2().then(data => {
- console.log("promise resolve:" + data);
- }).catch(error => {
- console.log("promise reject:" + error);
- })
-
- console.log(module2);
- console.log(module3);
-
- setTimeout(function(){
- console.log("定时器到点了");
- }, 1000)
优点:解决babel只能转换部分低级语法的问题,引入polyfill后可转换高级语法,比如Promise。
缺点:将所有高级语法进行转换,不管实际使用情况。
2、借助core.js按需引入(babel+core.js,使用core.js时可以不用polyfill):
安装core-js:
npm i core-js@3.13.0 -D
使用core-js:
配置文件中loader方式引入
- module: {
- rules: [{
- test: /\.js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- "presets": [
- ["@babel/preset-env", {
- useBuiltIns: "usage", //使用corejs的方式,表示按需加载
- corejs: { version: 3 }, //指定core-js的版本
- targets: { //要兼容的目标浏览器
- "chrome": "58",
- "ie": "9"
- }
- }]
- ],
- "cacheDirectory": false // 开启babel缓存,只编译未编译代码,可减少编译时间
- }
- }
- }]
- }
图片文件分为css引入图片和html插入图片。css加载图片都是背景图。小图片采用base64转换字符串,小图片、大图片都需要单独的loader插件来完成。
用到的处理图片的loader插件如下:
安装loader:
npm i file-loader@6.2.0 url-loader@4.1.1 -D
说明:url-loader基于file-loader,且多了能针对不同图片大小进行不同处理的功能。
配置loader:
- module: {
- rules: [{
- test: /\.(png|jpg|gif)$/,
- use: [
- {
- loader: 'url-loader', //url-loader依赖file-loader,使用了url-loader后file-loader可以不用
- options: {
- limit: 8192, //url-loader能将小于8k图片编译成base64,大的采用file-loader处理
- publicPath: './dist/images', //决定实际代码中的图片地址
- outputPath: 'images', //决定文件本地输出地址
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }]
- }
一定要注意webpack.config.js中publicPath路径,包含图片的样式打包后会放置在页面的style标签中,图片打包后会放置在dist/images目录下,根据页面和生成的图片的路径关系,所以publicPath为 './dist/images':
webpack.config.js:
- /**
- * 此文件是webpack配置文件,用于指定webpack去执行哪些任务
- */
- const path = require('path');
-
- module.exports = {
- entry: './src/js/index.js', // 由cmd执行目录决定
- output: {
- path: path.resolve(__dirname, 'dist'), // 由当前文件所在位置和要生成的dist位置关系决定
- filename: './js/bundle.js'
- },
- mode: 'development',
- //1、所有的loader都要添加在module对象的rules中
- //2、rules是一个数组,数组中的每一个对象就是一个loader
- //3、loader特点:下载后无需引入,只需申明
- module: {
- rules: [{
- test: /\.less$/, //匹配所有less文件
- use: [
- 'style-loader', //3、用于在html文档中创建一个style标签,将样式“塞”进去
- 'css-loader', //2、将less编译后的css转换为CommonJs的一个模块
- 'less-loader' //1、将less编译成为css,但不生成单独的css文件,在内存中
- ]
- }, {
- test: /\.m?js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-env']
- }
- }
- }, {
- test: /\.js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- "presets": [
- ["@babel/preset-env", {
- useBuiltIns: "usage", //按需引入需要使用polyfill
- corejs: { version: 3 }, //解决不能找到core-js的问题
- targets: { //解决兼容性处理哪些浏览器
- "chrome": "58",
- "ie": "9"
- }
- }]
- ],
- "cacheDirectory": false // 开启babel缓存
- }
- }
- }, {
- test: /\.(png|jpg|gif)$/,
- use: [
- {
- loader: 'url-loader',
- options: {
- limit: 8192,
- publicPath: './dist/images', //决定图片的url路径
- outputPath: 'images', //决定文件本地输出路径
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }]
- }
- };
各loader版本:
- {
- "name": "webpack4",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "@babel/core": "^7.11.6",
- "@babel/preset-env": "^7.11.5",
- "babel-loader": "^8.1.0",
- "css-loader": "^4.3.0",
- "file-loader": "^6.2.0",
- "less": "^3.12.2",
- "less-loader": "^7.0.1",
- "style-loader": "^2.0.0",
- "url-loader": "^4.1.1",
- "webpack": "^4.41.2",
- "webpack-cli": "^3.3.10"
- }
- }
index.js
- import func1 from './moudle1'
- import func2 from './moudle2'
- import '../css/demo.less'
-
- console.log(func1(1, 2));
- console.log(func2(2, 3));
- console.log("webpack!");
moudle1.js
- const fun1 = (a, b) => {
- console.log("a + b = ", a+b);
- }
-
- module.exports = fun1;
moudle2.js
- const fun2 = (a, b) => {
- console.log("a + b = ", a+b);
- }
-
- module.exports = fun2;
demo.less
- .demo1{
- width: 500px;
- height: 500px;
- background: #FF0000 url("../images/download.png");
- }
- .demo2{
- width: 200px;
- height: 200px;
- background: #000000;
- }
index.html
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
-
- <body>
- <div class='demo1'></div>
- <div class='demo2'></div>
- <script src="./dist/js/bundle.js"></script>
- </body>
-
- </html>
概述:html中的图片url-loader没法处理,它只能处理js中引入的图片/样式中的图片,不能处理html中的img标签,需要引入html-loader处理。
添加图片:在src/index.html添加两个img标签。
安装loader:
npm i html-loader@1.1.0 -D
配置loader:
- module: {
- rules: [{
- test: /\.(html)$/,
- use: {
- loader: 'html-loader' // html-loader找到图片后自动交给url-loader处理
- }
- }]
- }
完整代码:
webpack.config.js:
- /**
- * 此文件是webpack配置文件,用于指定webpack去执行哪些任务
- */
- const HtmlWebpackPlugin = require('html-webpack-plugin');
- const path = require('path');
-
- module.exports = {
- entry: './src/js/index.js', // 由cmd执行目录决定
- output: {
- path: path.resolve(__dirname, 'dist'), // 由当前文件所在位置和要生成的dist位置关系决定
- filename: './js/bundle.js'
- },
- mode: 'development',
- //1、所有的loader都要添加在module对象的rules中
- //2、rules是一个数组,数组中的每一个对象就是一个loader
- //3、loader特点:下载后无需引入,只需申明
- module: {
- rules: [{
- test: /\.less$/, //匹配所有less文件
- use: [
- 'style-loader', //3、用于在html文档中创建一个style标签,将样式“塞”进去
- 'css-loader', //2、将less编译后的css转换为CommonJs的一个模块
- 'less-loader' //1、将less编译成为css,但不生成单独的css文件,在内存中
- ]
- }, {
- test: /\.m?js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-env']
- }
- }
- }, {
- test: /\.(png|jpg|gif)$/,
- use: [
- {
- loader: 'url-loader',
- options: {
- limit: 8192,
- publicPath: './images', //决定图片的url路径
- outputPath: 'images', //决定文件本地输出路径
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }, {
- test: /\.(html)$/,
- use: {
- loader: 'html-loader'
- }
- }]
- },
- plugins: [new HtmlWebpackPlugin({
- template: "./src/index.html", // 以当前文件为模板创建新的html(1、结构和原来一样;2、会自动引入打包的资源),默认 ,路径由cmd执行目录决定
- filename: "index.html", // 打包后的index.html文件默认位于dist目录下
- })]
- };
一定要注意url-loader中的publicPath。
index.html:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
- <body>
- <div class="demo1"></div>
- <div class="demo2"></div>
- <div><img src="./images/react.png"/></div>
- </body>
- </html>
demo.less:
- .demo1{
- width: 200px;
- height: 200px;
- background-image: url("../images/react.png");
- background-size: cover;
- }
- .demo2{
- width: 200px;
- height: 200px;
- background-image: url("../images/vue.jpg");
- background-size: cover;
- }
package.json:
- {
- "name": "webpack4",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "@babel/core": "^7.11.6",
- "@babel/preset-env": "^7.11.5",
- "babel-loader": "^8.1.0",
- "css-loader": "^4.3.0",
- "file-loader": "^6.2.0",
- "html-loader": "^1.1.0",
- "html-webpack-plugin": "^3.2.0",
- "less": "^3.12.2",
- "less-loader": "^7.0.1",
- "style-loader": "^2.0.0",
- "url-loader": "^4.1.1",
- "webpack": "^4.41.2",
- "webpack-cli": "^3.3.10"
- },
- "dependencies": {}
- }
概述:html文件webpack不能解析,需要借助插件编译解析。
添加html文件:
安装插件Plugins
npm i html-webpack-plugin@3.2.0 -D
在webpack.config.js中引入插件(插件都需手动引入,而loader会自动加载):
const HtmlWebpackPlugin = require('html-webpack-plugin');
配置插件:
- plugins: [new HtmlWebpackPlugin({
- template: './src/index.html', //以当前文件为模板创建新的html(1、结构和原来一样;2、会自动引入打包的资源),默认。路径相对于npm命令执行所在目录。
- filename: 'index.html' // 打包后的index.html文件默认位于dist目录下
- })]
运行指令:
webpack
完整代码:
src/index.html:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
- <body>
- <div class='demo1'></div>
- <div class='demo2'></div>
- </body>
- </html>
src/js/index.js:
- import func1 from './moudle1'
- import func2 from './moudle2'
- import '../css/demo.less'
-
- const word = "webpack!";
- console.log("webpack!");
- console.log(func1(1, 2));
- func2().then(data=>{
- console.log(data);
- }).catch(error=>{
- console.log(error);
- })
-
删除
import '@babel/polyfill'
webpack.config.js:
- /**
- * 此文件是webpack配置文件,用于指定webpack去执行哪些任务
- */
- const HtmlWebpackPlugin = require('html-webpack-plugin');
- const path = require('path');
-
- module.exports = {
- entry: './src/js/index.js', // 由cmd执行目录决定
- output: {
- path: path.resolve(__dirname, 'dist'), // 由当前文件所在位置和要生成的dist位置关系决定
- filename: './js/bundle.js'
- },
- mode: 'development',
- //1、所有的loader都要添加在module对象的rules中
- //2、rules是一个数组,数组中的每一个对象就是一个loader
- //3、loader特点:下载后无需引入,只需申明
- module: {
- rules: [{
- test: /\.less$/, //匹配所有less文件
- use: [
- 'style-loader', //3、用于在html文档中创建一个style标签,将样式“塞”进去
- 'css-loader', //2、将less编译后的css转换为CommonJs的一个模块
- 'less-loader' //1、将less编译成为css,但不生成单独的css文件,在内存中
- ]
- }, {
- test: /\.m?js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-env']
- }
- }
- }, {
- test: /\.js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- "presets": [
- ["@babel/preset-env", {
- useBuiltIns: "usage", //按需引入需要使用polyfill
- corejs: { version: 3 }, //解决不能找到core-js的问题
- targets: { //解决兼容性处理哪些浏览器
- "chrome": "58",
- "ie": "9"
- }
- }]
- ],
- "cacheDirectory": false // 开启babel缓存
- }
- }
- }, {
- test: /\.(png|jpg|gif)$/,
- use: [
- {
- loader: 'url-loader',
- options: {
- limit: 8192,
- publicPath: './images', //决定图片的url路径
- outputPath: 'images', //决定文件本地输出路径
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }]
- },
- plugins: [new HtmlWebpackPlugin({
- template: "./src/index.html", // 以当前文件为模板创建新的html(1、结构和原来一样;2、会自动引入打包的资源),默认 ,路径由cmd执行目录决定
- filename: "index.html", // 打包后的index.html文件默认位于dist目录下
- })]
- };
概述:其它资源,比如图标,webpack不能解析,需要借助loader编译解析。
安装loader:
npm i file-loader@6.2.0 -D
配置loader:
- {
- test: /\.(eot|svg|woff|woff2|ttf|mp3|mp4|avi)$/,
- use: [
- {
- loader: 'file-loader',
- options: {
- outputPath: 'media', //决定文件本地输出路径
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }
src/index.html中添加字体标签:
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
-
- <body>
- <span class="icon iconfont icon-caiwuguanli"></span>
- <span class="icon iconfont icon-baojiaguanli"></span>
- <span class="icon iconfont icon-baoguanzhidantaitouguanli"></span>
- <span class="icon iconfont icon-caigoudingdan"></span>
- <span class="icon iconfont icon-cangchuguanli"></span>
- <span class="icon iconfont icon-caigoulujing"></span>
- <div class='demo1'></div>
- <div class='demo2'></div>
- <div><img src="./images/react.png" width="100" /></div>
- </body>
-
- </html>
添加字体样式文件src/css/iconfont.less:
- @font-face {
- font-family: "iconfont"; /* Project id */
- src: url('../media/iconfont.ttf?t=1621867822279') format('truetype');
- }
-
- .iconfont {
- font-family: "iconfont" !important;
- font-size: 16px;
- font-style: normal;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- }
-
- .icon-caiwuguanli:before {
- content: "\e609";
- }
-
- .icon-baojiaguanli:before {
- content: "\e60a";
- }
-
- .icon-baoguanzhidantaitouguanli:before {
- content: "\e60b";
- }
-
- .icon-caigoudingdan:before {
- content: "\e60c";
- }
-
- .icon-cangchuguanli:before {
- content: "\e60d";
- }
-
- .icon-caigoulujing:before {
- content: "\e60e";
- }
-
index.js中引入iconfont.less文件:
- import func1 from './moudle1'
- import func2 from './moudle2'
- import '../css/demo.less'
- import '../css/iconfont.less'
-
- const word = "webpack!";
- console.log("webpack!");
- console.log(func1(1, 2));
- func2().then(data=>{
- console.log(data);
- }).catch(error=>{
- console.log(error);
- })
-
运行指令:
webpack
文件夹结构:
iconfont.less(注意引用的字体路径):
- @font-face {
- font-family: "iconfont"; /* Project id */
- src: url('../media/iconfont.ttf?t=1621867822279') format('truetype');
- }
-
- .iconfont {
- font-family: "iconfont" !important;
- font-size: 16px;
- font-style: normal;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- }
-
- .icon-caiwuguanli:before {
- content: "\e609";
- }
-
- .icon-baojiaguanli:before {
- content: "\e60a";
- }
-
- .icon-baoguanzhidantaitouguanli:before {
- content: "\e60b";
- }
-
- .icon-caigoudingdan:before {
- content: "\e60c";
- }
-
- .icon-cangchuguanli:before {
- content: "\e60d";
- }
-
- .icon-caigoulujing:before {
- content: "\e60e";
- }
-
index.html:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
- <body>
- <span class="icon iconfont icon-caiwuguanli"></span>
- <span class="icon iconfont icon-baojiaguanli"></span>
- <span class="icon iconfont icon-baoguanzhidantaitouguanli"></span>
- <span class="icon iconfont icon-caigoudingdan"></span>
- <span class="icon iconfont icon-cangchuguanli"></span>
- <span class="icon iconfont icon-caigoulujing"></span>
- <div class="demo1"></div>
- <div class="demo2"></div>
- <div><img src="./images/react.png"/></div>
- </body>
- </html>
webpack.config.js:
- /**
- * 此文件是webpack配置文件,用于指定webpack去执行哪些任务
- */
- const HtmlWebpackPlugin = require('html-webpack-plugin');
- const path = require('path');
-
- module.exports = {
- entry: './src/js/index.js', // 由cmd执行目录决定
- output: {
- path: path.resolve(__dirname, 'dist'), // 由当前文件所在位置和要生成的dist位置关系决定
- filename: './js/bundle.js'
- },
- mode: 'development',
- //1、所有的loader都要添加在module对象的rules中
- //2、rules是一个数组,数组中的每一个对象就是一个loader
- //3、loader特点:下载后无需引入,只需申明
- module: {
- rules: [{
- test: /\.less$/, //匹配所有less文件
- use: [
- 'style-loader', //3、用于在html文档中创建一个style标签,将样式“塞”进去
- 'css-loader', //2、将less编译后的css转换为CommonJs的一个模块
- 'less-loader' //1、将less编译成为css,但不生成单独的css文件,在内存中
- ]
- }, {
- test: /\.m?js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-env']
- }
- }
- }, {
- test: /\.(png|jpg|gif)$/,
- use: [
- {
- loader: 'url-loader',
- options: {
- limit: 8192,
- //publicPath: '../dist/images', //决定图片的url路径
- outputPath: 'images', //决定文件本地输出路径
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }, {
- test: /\.(html)$/,
- use: {
- loader: 'html-loader'
- }
- }, {
- test: /\.(eot|svg|woff|woff2|ttf|mp3|mp4|avi)$/,
- use: [
- {
- loader: 'file-loader',
- options: {
- outputPath: 'media', //决定文件本地输出路径
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }]
- },
- plugins: [new HtmlWebpackPlugin({
- template: "./src/index.html", // 以当前文件为模板创建新的html(1、结构和原来一样;2、会自动引入打包的资源),默认 ,路径由cmd执行目录决定
- filename: "index.html", // 打包后的index.html文件默认位于dist目录下
- })]
- };
package.json:
- {
- "name": "webpack4",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "@babel/core": "^7.11.6",
- "@babel/preset-env": "^7.11.5",
- "babel-loader": "^8.1.0",
- "css-loader": "^4.3.0",
- "file-loader": "^6.2.0",
- "html-loader": "^1.1.0",
- "html-webpack-plugin": "^3.2.0",
- "less": "^3.12.2",
- "less-loader": "^7.0.1",
- "style-loader": "^2.0.0",
- "url-loader": "^4.1.1",
- "webpack": "^4.41.2",
- "webpack-cli": "^3.3.10"
- },
- "dependencies": {}
- }
由于代码可能有CommonJS等非浏览器支持的语法,每次都必须打包才行运行,虽然借助Webstorm等工具可以构建服务器环境,但实际上不能时时监控刷新。IDE提供的服务器之间访问的是打包后的文件,是否监听时时刷新看个人习惯。
以上:如果要方便的话,开发者需求的想法是,开发时方便调试,最后再打包。所以,官方提供了Webpack-dev-Server工具来解决这个问题,支持特性:
注:
此处是自动刷新整个页面 ,如果想做到局部刷新,则请浏览:二十二、HMR 热替换
1、安装loader:
npm i webpack-dev-server@3.11.2 -D
详情见:官网->指南->开发环境->使用webpack-dev-server
2、修改webpack配置对象:
- devServer: {
- open: true,
- compress: true,
- port: 3000,
- stats: 'minimal'//迷你型服务启动信息
- }
webpack.config.js:
- /**
- * 此文件是webpack配置文件,用于指定webpack去执行哪些任务
- */
- const HtmlWebpackPlugin = require('html-webpack-plugin');
- const path = require('path');
-
- module.exports = {
- entry: './src/js/index.js', // 由cmd执行目录决定
- output: {
- path: path.resolve(__dirname, 'dist'), // 由当前文件所在位置和要生成的dist位置关系决定
- filename: './js/bundle.js' // 直接在根目录下生成js文件夹及bundle.js文件
- },
- mode: 'development',
- //1、所有的loader都要添加在module对象的rules中
- //2、rules是一个数组,数组中的每一个对象就是一个loader
- //3、loader特点:下载后无需引入,只需申明
- module: {
- rules: [{
- test: /\.less$/, //匹配所有less文件
- use: [
- 'style-loader', //3、用于在html文档中创建一个style标签,将样式“塞”进去
- 'css-loader', //2、将less编译后的css转换为CommonJs的一个模块
- 'less-loader' //1、将less编译成为css,但不生成单独的css文件,在内存中
- ]
- }, {
- test: /\.m?js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-env']
- }
- }
- }, {
- test: /\.(png|jpg|gif)$/,
- use: [
- {
- loader: 'url-loader',
- options: {
- limit: 8192,
- //publicPath: '../dist/images', //决定图片的url路径
- outputPath: 'images', //决定文件本地输出路径
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }, {
- test: /\.(html)$/,
- use: {
- loader: 'html-loader'
- }
- }, {
- test: /\.(eot|svg|woff|woff2|ttf|mp3|mp4|avi)$/,
- use: [
- {
- loader: 'file-loader',
- options: {
- outputPath: 'media', //决定文件本地输出路径
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }]
- },
- plugins: [new HtmlWebpackPlugin({
- template: "./src/index.html", // 以当前文件为模板创建新的html(1、结构和原来一样;2、会自动引入打包的资源),默认 ,路径由cmd执行目录决定
- filename: "index.html", // 打包后的index.html文件默认位于dist目录下
- })],
- devServer: {
- open: true,
- compress: true,
- port: 8080,
- stats: 'minimal',//迷你型服务启动信息
- },
- };
3、修改url-loader部分配置:
4、修改package.json中scripts指令:
"start": "webpack-dev-server --open chrome --port 3000"
5、./index.html:
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
-
- <body>
- 1
- <div class='demo1'></div>
- <div class='demo2'></div>
- <div><img src="./src/images/bg.jpeg"/></div>
- <script src="./js/bundle.js"></script>
- </body>
-
- </html>
6、运行指令:
npm start
经过以上设置,处理的html是根目录下的index.html,打包后的js位于设置的根目录下的js文件夹下。
本地我们可以删除dist目录,还原打包之前再启动devServer测试效果。此时我们可以发现并不需要打包到本地,它是自动打包到内存让你时时预览调试的。也就是说:调试阶段,可以用devServer,完成了,再最终打包到本地即可。
多页面配置
如果我们想生成多个.html 文件,比如 index.html 和 main.html,此时,我们需要修改一下入口文件和出口文件:
- //入口文件
- entry: {
- //把需要加载的 js 以键值对方
- index : './src/js/index.js',
- main : './src/js/main.js'
- },
或
- //入口文件,也支持 ES6 的箭头函数
- entry: () => ({
- index : './src/js/index.js',
- main : './src/js/main.js'
- }),
出口文件,需要按照入口文件的名称进行打包,否则只会打包一个。
- //出口文件
- output: {
- //文件名
- filename : 'js/[name].js',
- }),
最后,我们要使用 HtmlWebpackPlugin 插件来设置自己想要的打包方案:
- //插件
- plugins: [
- new HtmlWebpackPlugin({
- template: "./src/index.html", //默认值
- filename: "index.html", //默认值
- chunks: ['index', 'main']
- }),
- new HtmlWebpackPlugin({
- template: "./src/main.html",
- filename: "main.html",
- chunks: ['main']
- }),
- ],
基本的 ESLint 实现,需要一下安装以下模块:
首先,先安装 eslint,然后安装配置信息:
- npm i eslint@7.2.0 -D //安装 eslint
-
- .\node_modules\.bin\eslint --init //安装配置信息
PS:期间会让你选择配置信息情况,根据你实际情况选择即可,生成:.eslintrc.json;
PS:网上也会别人生成的配置信息可以拿来用,也可以去官网 eslint.cn/demo 生成信息
再次,我们安装 eslint-loader 模块:
npm i eslint-loader@4.0.2 -D
最后,我们来配置 webpack.config.js:
- {
- test : /.js$/,
- loader: 'eslint-loader',
- //编译前执行
- enforce: 'pre',
- //不检查的目录
- exclude: /node_modules/
- },
防止错误飘红太多,干扰演示,我们注释掉大部分代码,写上示例:
var foo = bar;
测试打包和预览提示校验。
注意插件和loader的版本:
- {
- "name": "webpack4",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "build": "webpack --config ./config/webpack.prod.config.js",
- "dev": "webpack-dev-server --open chrome --port 8080 --config ./config/webpack.dev.config.js",
- "start": "webpack-dev-server --open chrome --port 8080 --config ./config/webpack.dev.config.js"
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "@babel/core": "^7.11.6",
- "@babel/polyfill": "^7.12.1",
- "@babel/preset-env": "^7.11.5",
- "autoprefixer": "^9.8.6",
- "axios": "^0.22.0",
- "babel-loader": "^8.1.0",
- "clean-webpack-plugin": "^4.0.0",
- "core-js": "^3.13.0",
- "css-loader": "^4.3.0",
- "eslint": "^7.2.0",
- "eslint-loader": "^4.0.2",
- "file-loader": "^6.2.0",
- "html-loader": "^1.1.0",
- "html-webpack-plugin": "^3.2.0",
- "less": "^3.12.2",
- "less-loader": "^7.0.1",
- "mini-css-extract-plugin": "^1.6.0",
- "optimize-css-assets-webpack-plugin": "^6.0.0",
- "postcss-flexbugs-fixes": "^4.2.1",
- "postcss-loader": "^3.0.0",
- "postcss-normalize": "^8.0.1",
- "postcss-preset-env": "^6.7.0",
- "style-loader": "^2.0.0",
- "url-loader": "^4.1.1",
- "vue-loader": "^15.9.8",
- "vue-template-compiler": "^2.6.14",
- "webpack": "^4.41.2",
- "webpack-cli": "^3.3.10",
- "webpack-dev-server": "^3.11.2",
- "webpack-merge": "^5.8.0"
- },
- "dependencies": {
- "vue": "^2.6.14"
- }
- }
cnpm i mini-css-extract-plugin@1.6.0 -D
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
- new MiniCssExtractPlugin({
- filename: 'css/[name].css'
- })
- {
- test: /\.less$/, //匹配所有less文件
- use: [
- {
- loader: MiniCssExtractPlugin.loader,
- options: {
- publicPath: '../'
- }
- },
- 'css-loader', //2、将less编译后的css转换为CommonJs的一个模块
- 'less-loader' //1、将less编译成为css,但不生成单独的css文件,在内存中
- ]
- }
package.json
- "scripts": {
- "build": "webpack",
- "build": "webpack --config ./config/webpack.prod.js",
- "dev": "webpack-dev-server --open chrome --port 8080 --config ./config/webpack.dev.js"
- },
npm run dev
完整代码:
src/index.html:
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
-
- <body>
- <span class="icon iconfont icon-caiwuguanli"></span>
- <span class="icon iconfont icon-baojiaguanli"></span>
- <span class="icon iconfont icon-baoguanzhidantaitouguanli"></span>
- <span class="icon iconfont icon-caigoudingdan"></span>
- <span class="icon iconfont icon-cangchuguanli"></span>
- <span class="icon iconfont icon-caigoulujing"></span>
- <div class='demo1'></div>
- <div class='demo2'></div>
- <div><img src="./images/react.png" width="100" /></div>
- </body>
-
- </html>
config/webpack.dev.js:
- const path = require('path')
- const HtmlWebpackPlugin = require("html-webpack-plugin")
- const MiniCssExtractPlugin = require('mini-css-extract-plugin')
-
- module.exports = {
- entry: './src/js/index.js', // 由cmd执行目录决定
- output: {
- path: path.resolve(__dirname, 'dist'), // 由当前文件所在位置和要生成的dist位置关系决定
- filename: './js/bundle.js'
- },
- module: {
- rules: [
- {
- test: /\.less$/,
- use: [
- {
- loader: MiniCssExtractPlugin.loader,
- options: {
- publicPath: '../'
- }
- },
- 'css-loader',
- 'less-loader'
- ]
- },
- {
- test: /\.m?js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- "presets": [
- ["@babel/preset-env", {
- useBuiltIns: "usage", //按需引入需要使用polyfill
- corejs: { version: 3 }, //解决不能找到core-js的问题
- targets: { //解决兼容性处理哪些浏览器
- "chrome": "58",
- "ie": "9"
- }
- }]
- ],
- "cacheDirectory": false // 开启babel缓存,只编译未编译代码,可减少编译时间
- }
- }
- },
- {
- test: /\.(png|jpg|gif|jpeg)$/,
- use: {
- loader: 'url-loader',
- options: {
- limit: 8192,
- //publicPath: '../images',
- outputPath: 'images',
- name: '[hash:5].[ext]'
- }
- }
- },
- {
- test: /\.(html)$/,
- use: {
- loader: 'html-loader'
- }
- },
- {
- test: /\.(eot|svg|woff|woff2|ttf|mp3|mp4)$/,
- use: [{
- loader: 'file-loader',
- options: {
- //publicPath: '../media',
- outputPath: 'media',
- name: '[hash:5].[ext]'
- }
- }]
- }
- ]
- },
- plugins: [new HtmlWebpackPlugin({
- template: "./src/index.html", // 以当前文件为模板创建新的html(1、结构和原来一样;2、会自动引入打包的资源),默认 ,路径由cmd执行目录决定
- filename: "index.html", // 打包后的index.html文件默认位于dist目录下
- minify: {
- removeComments: true,
- collapseWhitespace: true,
- removeRedundantAttributes: true,
- useShortDoctype: true,
- removeEmptyAttributes: true,
- removeStyleLinkTypeAttributes: true,
- keepClosingSlash: true,
- minifyJS: true,
- minifyCSS: true,
- minifyURLs: true,
- }
- }), new MiniCssExtractPlugin({
- filename: './css/[name].css'
- })],
- devServer: {
- open: true,
- compress: true,
- port: 8080,
- hot: true
- }
- }
一定要注意:这里使用url-loader生成的背景图片是在css文件中引入,所有这里查找图片是从build/css目录去build/images目录查找:
- {
- test: /\.(png|jpg|gif)$/,
- use: [
- {
- loader: 'url-loader',
- options: {
- limit: 8192, //url-loader能将小于8k图片编译成base64,file-loader不具此功能
- //publicPath: '../images', //决定图片的url路径
- outputPath: 'images', //决定文件本地输出路径
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }
config/webpack.prod.js:
- const path = require('path')
- const HtmlWebpackPlugin = require("html-webpack-plugin")
- const MiniCssExtractPlugin = require('mini-css-extract-plugin')
-
- module.exports = {
- entry: './src/js/index.js',
- output: {
- path: path.resolve(__dirname, '../dist'),
- filename: './js/bundle.js'
- },
- module: {
- rules: [
- {
- test: /\.less$/,
- use: [
- {
- loader: MiniCssExtractPlugin.loader,
- options: {
- publicPath: '../'
- }
- },
- 'css-loader',
- 'less-loader'
- ]
- },
- {
- test: /\.m?js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- "presets": [
- ["@babel/preset-env", {
- useBuiltIns: "usage", //按需引入需要使用polyfill
- corejs: { version: 3 }, //解决不能找到core-js的问题
- targets: { //解决兼容性处理哪些浏览器
- "chrome": "58",
- "ie": "9"
- }
- }]
- ],
- "cacheDirectory": false // 开启babel缓存,只编译未编译代码,可减少编译时间
- }
- }
- },
- {
- test: /\.(png|jpg|gif|jpeg)$/,
- use: {
- loader: 'url-loader',
- options: {
- limit: 8192,
- //publicPath: '../images',
- outputPath: 'images',
- name: '[hash:5].[ext]'
- }
- }
- },
- {
- test: /\.(html)$/,
- use: {
- loader: 'html-loader'
- }
- },
- {
- test: /\.(eot|svg|woff|woff2|ttf|mp3|mp4)$/,
- use: [{
- loader: 'file-loader',
- options: {
- //publicPath: '../media',
- outputPath: 'media',
- name: '[hash:5].[ext]'
- }
- }]
- }
- ]
- },
- plugins: [new HtmlWebpackPlugin({
- template: './src/index.html',
- minify: {
- removeComments: true,
- collapseWhitespace: true,
- removeRedundantAttributes: true,
- useShortDoctype: true,
- removeEmptyAttributes: true,
- removeStyleLinkTypeAttributes: true,
- keepClosingSlash: true,
- minifyJS: true,
- minifyCSS: true,
- minifyURLs: true,
- }
- }), new MiniCssExtractPlugin({
- filename: './css/[name].css'
- })]
- }
方法一:
cnpm i postcss-loader@3.0.0 postcss-flexbugs-fixes@4.2.1 postcss-preset-env@6.7.0 postcss-normalize@8.0.1 autoprefixer@9.8.6 -D
- {
- loader: require.resolve('postcss-loader'),
- options: {
- ident: 'postcss',
- plugins: () => [
- require('postcss-flexbugs-fixes'),
- require('postcss-preset-env')({
- autoprefixer: {
- flexbox: 'no-2009',
- },
- stage: 3,
- }),
- require('postcss-normalize')()
- ],
- sourceMap: true,
- },
- }
- /**
- * 此文件是webpack配置文件,用于指定webpack去执行哪些任务
- */
-
- const HtmlWebpackPlugin = require('html-webpack-plugin');
- const MiniCssExtractPlugin = require('mini-css-extract-plugin');
- const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
- const path = require('path');
-
- module.exports = {
- entry: './src/js/index.js', // 由cmd执行目录决定
- output: {
- path: path.resolve(__dirname, '../build'), // 由当前文件所在位置和要生成的build位置关系决定
- filename: './js/bundle.js',
- publicPath: '/'
- },
- mode: 'production',
- devtool: 'cheap-module-source-map',
- module: {
- rules: [
- {
- test: /\.js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- "presets": [
- ["@babel/preset-env", {
- useBuiltIns: "usage", //按需引入需要使用polyfill
- corejs: { version: 3 }, //解决不能找到core-js的问题
- targets: { //解决兼容性处理哪些浏览器
- "chrome": "58",
- "ie": "9"
- }
- }]
- ],
- "cacheDirectory": false // 开启babel缓存,只编译未编译代码,可减少编译时间
- }
- }
- },
- {
- test: /\.less$/, //匹配所有less文件
- use: [
- MiniCssExtractPlugin.loader, //3、用于在html文档中创建一个style标签,将样式“塞”进去
- 'css-loader', //2、将less编译后的css转换为CommonJs的一个模块
- {
- loader: require.resolve('postcss-loader'),
- options: {
- ident: 'postcss',
- plugins: () => [
- require('postcss-flexbugs-fixes'),
- require('postcss-preset-env')({
- autoprefixer: {
- flexbox: 'no-2009',
- },
- stage: 3,
- }),
- require('postcss-normalize')()
- ],
- sourceMap: true,
- },
- },
- 'less-loader' //1、将less编译成为css,但不生成单独的css文件,在内存中
- ]
- }, {
- test: /\.(png|jpg|gif)$/,
- use: [
- {
- loader: 'url-loader',
- options: {
- limit: 8192, //url-loader能将小于8k图片编译成base64,file-loader不具此功能
- //publicPath: '../images', //决定图片的url路径
- outputPath: 'images', //决定文件本地输出路径
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }, {
- test: /\.(eot|svg|woff|woff2|ttf|mp3|mp4|avi)$/,
- use: [
- {
- loader: 'file-loader',
- options: {
- outputPath: 'media', //决定文件本地输出路径
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }, {
- test: /\.(html)$/,
- use: {
- loader: 'html-loader'
- }
- }
- ]
- },
- plugins: [new HtmlWebpackPlugin({
- template: "./src/index.html", // 以当前文件为模板创建新的html(1、结构和原来一样;2、会自动引入打包的资源),默认 ,路径由cmd执行目录决定
- filename: "index.html", // 打包后的index.html文件默认位于dist目录下
- minify: {
- removeComments: true,
- collapseWhitespace: true,
- removeRedundantAttributes: true,
- useShortDoctype: true,
- removeStyleLinkTypeAttributes: true,
- keepClosingSlash: true,
- minifyJS: true,
- minifyCSS: true,
- minifyURLs: true,
- }
- }), new MiniCssExtractPlugin({
- filename: 'css/[name].css'
- }), new OptimizeCSSAssetsPlugin({
- cssProcessorPluginOptions: {
- preset: [
- 'default',
- {
- discardComments: {
- removeAll: true
- },
- },
- ]
- },
- cssProcessorOptions: {
- map: {
- inline: false,
- annotation: true
- }
- }
- })]
- };
- #Browsers that we support
-
- last 1 version
- > 1%
- IE 10 # sorry
方法二:
npm i postcss-loader@3.0.0 -D
- {
- test: /\.css$/,
- //执行顺序是从右往左边
- use : [
- {
- loader: MiniCssExtractPlugin.loader,
- options: {
- publicPath : '../'
- }
- },
- {
- loader: "css-loader",
- options: {
- importLoaders : 1 //由于采用了@import,被导入的css无法解析,需要设置importLoaders=1即可
- }
- },
- 'postcss-loader'
- ]
- }
npm i autoprefixer@9.8.6 -D
这个插件会在需要兼容性的样式中加上CSS前缀,比如:-ms、-webkit等。在根目录创建postcss.config.js用来配置兼容的浏览器,当postcss-loader被调用时postcss.config.js文件就会执行。
postcss.config.js
- /*
- postcss配置文件
- */
-
- const AutoPrefixer = require('autoprefixer');
-
- module.exports = {
- plugins : [
- new AutoPrefixer({
- overrideBrowserslist : [
- '> 0.15% in CN'
- //'ie >= 8'
- ]
- })
- ]
- };
在index.css中添加css样式:
- display: flex;
- transform: rotateY(130deg);
编译后看编译完成的css文件中是否有兼容性代码。
npm i postcss-preset-env@6.7.0 -D
index.css中添加如下样式:
- :root{
- --green:green;
- };
-
- h1{
- color:var(--green);
- }
postcss.config.js修改如下:
- //请注意:如果使用postcss-preset-env,就删除autoprefixer
- //因为post-preset-env集成了autoprefixer,不需要再引入设置
-
- // const AutoPrefixer = require('autoprefixer');
- const PostPresetEnv = require('postcss-preset-env');
-
- module.exports = {
- plugins : [
- new PostPresetEnv({
- browsers : [
- '> 0.15% in CN'
- //'ie >= 8'
- ]
- })
- ]
- };
编译后看编译完成的css文件中是否有兼容性代码。
Scss
和 Less 一样,Scss 也是 Sass 的一种使用较多的语法;
cnpm install sass sass-loader node-sass -D
具体配置基本和 Less 一样,先创建.scss 文件,并引入:
- {
- test: /\.scss$/,
- //从右向左执行
- use : [
- MiniCssExtractPlugin.loader,
- 'css-loader',
- 'sass-loader'
- ]
- },
TypeScript
越来越流行的 TypeScript,JavaScript 的一个超集。
cnpm i typescript ts-loader -D
- {
- test: /\.ts$/,
- use : 'ts-loader',
- }
编写一个.ts 文件,然后通过 import 导入到 index.js。
- //type.ts
- export const output = (content : string) => {
- return content
- }
-
- //import ts
- import { output } from './type.ts'
- console.log(output('Mr.Lee'))
如果要省略掉 import 中文件后缀,需要配置:
- module.exports = {
- resolve: {
- extensions: ['.ts', '.js']
- }
- }
PS:需要创建 tsconfig.json 文件。
为何要压缩代码?什么情况下要压缩?
答:在生产环境下打包时节约资源。
既然在生产环境,那首先要把打包的配置更改为生产环境:
mode: "production"
调节为生产环境打包,就会自动将 js 代码进行打包,不需要单独设置。
压缩css
npm i optimize-css-assets-webpack-plugin@6.0.0 -D
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
- new OptimizeCSSAssetsPlugin({
- cssProcessorPluginOptions: {
- preset: [
- 'default',
- {
- discardComments: {
- removeAll: true
- },
- },
- ]
- },
- cssProcessorOptions: {
- map: {
- inline: false,
- annotation: true
- }
- }
- })
- npm run build
- serve -s build
webpack.prod.js:
- /**
- * 此文件是webpack配置文件,用于指定webpack去执行哪些任务
- */
-
- const HtmlWebpackPlugin = require('html-webpack-plugin');
- const MiniCssExtractPlugin = require('mini-css-extract-plugin');
- const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
- const path = require('path');
-
- module.exports = {
- entry: './src/js/index.js', // 由cmd执行目录决定
- output: {
- path: path.resolve(__dirname, '../build'), // 由当前文件所在位置和要生成的build位置关系决定
- filename: './js/bundle.js',
- publicPath: '/'
- },
- mode: 'production',
- devtool: 'cheap-module-source-map',
- module: {
- rules: [
- {
- test: /\.js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- "presets": [
- ["@babel/preset-env", {
- useBuiltIns: "usage", //按需引入需要使用polyfill
- corejs: { version: 3 }, //解决不能找到core-js的问题
- targets: { //解决兼容性处理哪些浏览器
- "chrome": "58",
- "ie": "9"
- }
- }]
- ],
- "cacheDirectory": false // 开启babel缓存,只编译未编译代码,可减少编译时间
- }
- }
- },
- {
- test: /\.less$/, //匹配所有less文件
- use: [
- MiniCssExtractPlugin.loader, //3、用于在html文档中创建一个style标签,将样式“塞”进去
- 'css-loader', //2、将less编译后的css转换为CommonJs的一个模块
- 'less-loader' //1、将less编译成为css,但不生成单独的css文件,在内存中
- ]
- }, {
- test: /\.(png|jpg|gif)$/,
- use: [
- {
- loader: 'url-loader',
- options: {
- limit: 8192, //url-loader能将小于8k图片编译成base64,file-loader不具此功能
- publicPath: '../images', //决定图片的url路径
- outputPath: 'images', //决定文件本地输出路径
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }, {
- test: /\.(eot|svg|woff|woff2|ttf|mp3|mp4|avi)$/,
- use: [
- {
- loader: 'file-loader',
- options: {
- outputPath: 'media', //决定文件本地输出路径
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }, {
- test: /\.(html)$/,
- use: {
- loader: 'html-loader'
- }
- }
- ]
- },
- plugins: [new HtmlWebpackPlugin({
- template: "./src/index.html", // 以当前文件为模板创建新的html(1、结构和原来一样;2、会自动引入打包的资源),默认 ,路径由cmd执行目录决定
- filename: "index.html", // 打包后的index.html文件默认位于dist目录下
- }), new MiniCssExtractPlugin({
- filename: 'css/[name].css'
- }), new OptimizeCSSAssetsPlugin({
- cssProcessorPluginOptions: {
- preset: [
- 'default',
- {
- discardComments: {
- removeAll: true
- },
- },
- ]
- },
- cssProcessorOptions: {
- map: {
- inline: false,
- annotation: true
- }
- }
- })]
- };
压缩html
修改前面安装的html-webpack-plugin插件配置:
- new HtmlWebpackPlugin({
- template: './src/index.html', //以当前文件为模板创建新的html(1、结构和原来一样;2、会自动引入打包的资源)
- minify: {
- removeComments: true, // 是否移除注释 默认 false
- collapseWhitespace: true, // 是否去除空格,默认 false
- removeRedundantAttributes: true,
- useShortDoctype: true,
- removeEmptyAttributes: true,
- removeStyleLinkTypeAttributes: true,
- keepClosingSlash: true,
- minifyJS: true,
- minifyCSS: true,
- minifyURLs: true,
- }
- })
JS中,在 import 文件时如果不限定后缀会出现无法载入的情况,我们可以使用Resolve 模块中的extensions 来进行解析:
- //模块解析
- resolve: {
- //导入文件查找的限定后缀,默认.js 和.json
- extensions: ['.ts', '.js', '.json' ]
- },
PS:导入语句时如果检测不到指定的会报错。
alias 配置可以用别名的方式,将导入路径映射成一个新的路径:
- //设置一个别名路径(绝对路径)
- alias: {
- css : path.resolve(__dirname, './src/css')
- }
-
- require('css/base.css');
modules 配置可以指定 webpack 的解析模块目录:
- //找到解析模块目录,如果当前找不到就不断往上一层找
- modules: ['node_modules']
-
- //也可以设置指定目录直接查找,检查查找次数
- modules: [path.resolve(__dirname, '../node_modules')]
PS:自然,也可以设置第二参数,防止第一参数找不到报错。
上述配置最终效果:
- resolve: {
- //导入语句省略后缀
- extensions: ['.ts', '.js', '.json'],
- //导入路径的别名
- alias: {
- css: path.resolve(__dirname, './src/css')
- },
- //解析模块目录
- // modules: [path.resolve(__dirname, '../node_modules'), 'node_modules']
- },
Source-Map 可以将编译、打包、压缩后的代码映射到源代码上,你打包或运行的代码是编译后的,报错后devtool映射能指向你源代码的位置上,它会生成一个.map 文件。
配置方式:
devtool: 'source-map'
根据不同的方式,有下面几种类型:
在开发环境和生产环境,我们该如何选择?开发要求速度快,调试方便推荐:
1、watch 监听
每次打包,都比较烦,耗时耗力,有一种解决方案:watch 文件监听。这种解决方案,就是你打包时,就挂着监听你原始文件的变化,从而自动更新。
- //文件监听,默认 false
- watch: true,
-
- //开启 watch,下面才有意义
- watchOptions: {
- //不监听解析模块目录
- ignored: /node_modules/,
-
- //防止更新频率太快,默认 300 毫秒,意味监听到变化后 500 毫秒再编译
- aggregateTimeout: 500,
-
- //轮询间隔时间,1 秒,询问系统指定文件是否变化了
- poll: 1000
- },
2、clean 清理
每次打包之前都要手动清空设置的打包目录,因为不清空的话,改了配置目录就会多出废目录或文件。所以,使用 clean-webpack-plugin 插件,可以解决这个问题。
npm i clean-webpack-plugin -D
- //获取 clean 清理插件
- const { CleanWebpackPlugin } = require('clean-webpack-plugin')
-
- //插件
- plugins: [
- new CleanWebpackPlugin()
- ]
页面调试有一个问题,就是当我们编辑了 css 或 js它会自动刷新。但如果有大量的 css 或 js,一个小修改就要全部刷新影响开发性能。而 HMR 热替换就是解决这个问题,当 css 或 js 修改时只刷新修改的部分。对于html 文件,它就一个文件,不需要热替换。开启 HMR 热替换,可以在启动服务时加上--hot,或者在 devServer 配置:
- devServer: {
- hot : true
- }
对于 css 的热替换,需要使用 style-loader:
- {
- test: /\.less$/,
- use: [
- 'style-loader',
- 'css-loader',
- 'less-loader'
- ]
- }
当开启了 HMR 热替换之后,发现 html 文件修改后无法自动更新了,此时我们需要在入口文件加入这个 html 文件即可:
- entry: [
- './src/js/index.js',
- './src/index.html'
- ],
对于 js 的热替换,只要在入口文件对加载的其它 js 文件进行设置即可:
- import name from './module'
- console.log(name);
-
- if (module.hot) {
- module.hot.accept('./module', () => {
- console.log(name);
- })
- }
这里提供两个远程 json 文件,会返回一些数据用于测试跨域问题:
https://cdn.liyanhui.com/data.json (可跨域,设置过)
https://cdn.ycku.com/data.json (不可跨域,默认)
安装 axios用于 ajax 测试:
npm install axios
编写代码,测试数据:
- import axios from 'axios'
-
- axios.get('https://cdn.liyanhui.com/data.json').then(res => {
- console.log(res.data)
- })
如果把地址中的 liyanhui 换成 ycku 的话,会出现跨域的问题。
通过 devServer 设置代理模式,来解决跨域问题:
- devServer: {
- //设置代理
- proxy: {
- //匹配前缀为/api
- '/api': {
- //目标域名 ip
- target: 'https://cdn.ycku.com',
- //改变源
- changeOrigin: true,
- //重写 url, 去掉 /api
- pathRewrite: {
- '^/api': ''
- }
- }
- }
- }
axios.get('/api/data.json').then(res => { ... }).catch(error => {})
安装vue及相关插件
- cnpm i vue@2.6.14 -S
- cnpm i vue-loader@15.9.8 vue-template-compiler@2.6.14 -D
webpack.config.js中解构VueLoaderPlugin:
const { VueLoaderPlugin } = require("vue-loader");
webpack.config.js中加入vue-loader:
- {
- test: /\.vue$/, //匹配vue文件
- use: 'vue-loader'
- }
及VueLoaderPlugin插件:
plugins: [new VueLoaderPlugin()]
完整的webpack.config.js:
-
- /**
- * 此文件是webpack配置文件,用于指定webpack去执行哪些任务
- */
- const HtmlWebpackPlugin = require('html-webpack-plugin');
- const { VueLoaderPlugin } = require("vue-loader");
- const path = require('path');
-
- module.exports = {
- entry: './src/js/index.js', // 由cmd执行目录决定
- output: {
- path: path.resolve(__dirname, 'dist'), // 由当前文件所在位置和要生成的dist位置关系决定
- filename: './js/bundle.js'
- },
- mode: 'development',
- //1、所有的loader都要添加在module对象的rules中
- //2、rules是一个数组,数组中的每一个对象就是一个loader
- //3、loader特点:下载后无需引入,只需申明
- module: {
- rules: [{
- test: /\.vue$/, //匹配所有less文件
- use: 'vue-loader'
- }, {
- test: /\.less$/, //匹配所有less文件
- use: [
- 'style-loader', //3、用于在html文档中创建一个style标签,将样式“塞”进去
- 'css-loader', //2、将less编译后的css转换为CommonJs的一个模块
- 'less-loader' //1、将less编译成为css,但不生成单独的css文件,在内存中
- ]
- }, {
- test: /\.m?js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-env']
- }
- }
- }, {
- test: /\.js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- "presets": [
- ["@babel/preset-env", {
- useBuiltIns: "usage", //按需引入需要使用polyfill
- corejs: { version: 3 }, //解决不能找到core-js的问题
- targets: { //解决兼容性处理哪些浏览器
- "chrome": "58",
- "ie": "9"
- }
- }]
- ],
- "cacheDirectory": false // 开启babel缓存
- }
- }
- }, {
- test: /\.(png|jpg|gif)$/,
- use: [
- {
- loader: 'url-loader',
- options: {
- limit: 8192,
- publicPath: './images', //决定图片的url路径
- outputPath: 'images', //决定文件本地输出路径
- name: '[hash:5].[ext]' //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- }]
- },
- plugins: [new VueLoaderPlugin()]
- };
新建vue相关文件:
src/ App.vue:
- <template>
- <div>
- {{message}}
- </div>
- </template>
-
- <script>
- export default {
- data() {
- return {
- message: 'Hello Vue!'
- }
- }
- }
- </script>
src/index.js:
- import Vue from 'vue'
- import App from './App.vue'
-
- new Vue({
- render: h => h(App)
- }).$mount('#app')
-
dist/index.html:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
- <body>
- <div id='app'></div>
- <script type="text/javascript" src="./js/bundle.js"></script></body>
- </html>
最后使用”npm run build“ 命令编译后打开”dist/index.html“页面即可查看最终效果。
当配置文件写的越发繁杂时,发现生产环境的配置和开发环境配置有冲突。此时,我们希望有两套配置文件,一套用于开发环境,一套用于生产环境。这里使用js合并插件webpack-merge来实现配置文件的分离保存。
1、创建文件夹config,将webpack.config.js复制两份:
./config/webpack.dev.config.js
./config/webpack.prod.config.js
2、将原先的webpack.config.js改为webpack.base.config.js,然后分离代码:
cnpm i webpack-merge -D
- //合并js插件
- const{ merge } = require('webpack-merge')
-
- //基础配置
- const base = require('./base.config')
-
- //开发环境配置
- module.exports = merge(base,{
- ...
- })
webpack.base.config.js:
- // 路径
- const path = require("path");
- // html插件
- const HtmlWebpackPlugin = require("html-webpack-plugin");
- // 提取css为单独文件插件
- const MiniCssExtractPlugin = require("mini-css-extract-plugin");
-
- module.exports = {
- // 入口文件
- entry: "./src/js/index.js", // 由cmd执行目录决定
- // 出口文件
- output: {
- path: path.resolve(__dirname, "../dist"), // 由当前文件所在位置和要生成的dist位置关系决定
- filename: "./js/bundle.js"
- },
-
- // 模块解析
- resolve: {
- // 导入语句省略后缀
- extensions: [".ts", ".js", ".json", ".css", ".less", ".scss"],
- // 导入路径的别名
- alias: {
- css: path.resolve(__dirname, "./src/css")
- },
- // 解析模块目录
- modules: [path.resolve(__dirname, "../node_modules"), "node_modules"]
- },
-
- // 模块
- module: {
- rules: [
- {
- test: /\.less$/, // 匹配所有less文件
- use: [
- {
- loader: MiniCssExtractPlugin.loader,
- options: {
- publicPath: "../"
- }
- },
- "css-loader", // 2、将less编译后的css转换为CommonJs的一个模块
- "less-loader" // 1、将less编译成为css,但不生成单独的css文件,在内存中
- ]
- },
- {
- test: /\.js$/,
- exclude: /(node_modules)/,
- use: {
- loader: "babel-loader",
- options: {
- presets: [
- [
- "@babel/preset-env",
- {
- useBuiltIns: "usage", // 按需引入需要使用polyfill
- corejs: { version: 3 }, // 解决不能找到core-js的问题
- targets: {
- // 解决兼容性处理哪些浏览器
- chrome: "58",
- ie: "9"
- }
- }
- ]
- ],
- cacheDirectory: false // 开启babel缓存,只编译未编译代码,可减少编译时间
- }
- }
- },
- {
- test: /\.(png|jpg|gif)$/,
- use: [
- {
- loader: "url-loader", //url-loader依赖file-loader,使用了url-loader后file-loader可以不用
- options: {
- limit: 8192, //url-loader能将小于8k图片编译成base64,大的采用file-loader处理
- //publicPath: "./images", //决定图片的url路径,less处设置了,此处就不需要了,不然html中的图片路径会出错
- outputPath: "./images", //决定文件本地输出路径
- name: "[hash:5].[ext]" //修改文件名称,[hash:5]取hash值前5位,[ext]文件扩展名
- }
- }
- ]
- },
- {
- test: /\.(html)$/,
- use: {
- loader: "html-loader" // html-loader找到图片后自动交给url-loader处理
- }
- }
- ]
- },
- //插件
- plugins: [
- new HtmlWebpackPlugin({
- template: "./src/index.html", // 以当前文件为模板创建新的html(1、结构和原来一样;2、会自动引入打包的资源),默认 ,路径由cmd执行目录决定
- filename: "index.html", // 打包后的index.html文件默认位于dist目录下
- minify: {
- removeComments: true, // 是否移除注释 默认 false
- collapseWhitespace: true, // 是否去除空格,默认 false
- removeRedundantAttributes: true,
- useShortDoctype: true,
- removeEmptyAttributes: true,
- removeStyleLinkTypeAttributes: true,
- keepClosingSlash: true,
- minifyJS: true,
- minifyCSS: true,
- minifyURLs: true
- }
- }),
- new MiniCssExtractPlugin({
- filename: "css/[name].css"
- })
- ]
- };
webpack.dev.config.js
- // 合并js插件
- const { merge } = require("webpack-merge");
- // 公共基础配置
- const base = require("./webpack.base.config");
-
- // 开发环境配置
- module.exports = merge(base, {
- // devServer
- devServer: {
- open: true,
- compress: true,
- port: 8080,
- stats: "minimal", //迷你型服务启动信息
- // 代理
- proxy: {
- "/api": {
- target: "https://cdn.ycku.com",
- changeOrigin: true,
- pathRewrite: {
- "^/api": ""
- }
- }
- }
- },
-
- // devTool
- devtool: "eval-source-map",
-
- // 开发模式
- mode: "development"
- });
webpack.prod.config.js:
- // 合并js插件
- const { merge } = require("webpack-merge");
- // 公共基础配置
- const base = require("./webpack.base.config");
- // css压缩插件
- const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
- // 清理打包目录插件
- const { CleanWebpackPlugin } = require("clean-webpack-plugin");
-
- module.exports = merge(base, {
- //devTool
- devtool: "source-map",
-
- //生产模式
- mode: "production",
- //监听
- watch: true,
-
- //监听选项,当true时才有效
- watchOptions: {
- //不监听解析模块目录
- ignored: /node_modules/,
- //更新频率
- aggregateTimeout: 500,
- //轮询
- poll: 1000
- },
- plugins: [
- new OptimizeCSSAssetsPlugin({
- cssProcessorPluginOptions: {
- preset: [
- "default",
- {
- discardComments: {
- removeAll: true
- }
- }
- ]
- },
- cssProcessorOptions: {
- map: {
- inline: false,
- annotation: true
- }
- }
- }),
- new CleanWebpackPlugin()
- ]
- });
修改package.json的指令:
- "dev": "webpack-dev-server --open chrome --port 3000 --config ./config/webpack.dev.config.js",
- "start": "webpack-dev-server --open chrome --port 3000 --config ./config/webpack.dev.config.js",
- "build": "webpack --config ./config/webpack.prod.config.js"
- npm start
- npm run dev
npm run build
生产环境代码需要部署到服务器上才能运行,serve这个库能够快速帮我们搭建一个静态资源服务器:
npm i serve -g
serve -s build -p 5000
path:仅告诉Webpack打包结果存储位置,必须是绝对路径。
outputPath:仅告诉各插件所生成文件的存放位置,该位置以path设置路径为基础,比如:output输出的js、url-loader解析的图片、HtmlWebpackPlugin生成的html文件都会存放在以path为基础的目录下。
publicPath:并不会对生成文件的路径造成影响,主要是在生产模式下,对你的页面里面引入的资源的路径做对应的补全,常见的就是css文件里面引入的图片、html文件里的url值补全。
请注意观察如下webpack.base.config.js文件中publicPath、outputPath及单独css文件夹设置:
项目路径
webpack.base.config.js:
- const path = require('path')
- const HtmlWebpackPlugin = require("html-webpack-plugin")
- const MiniCssExtractPlugin = require('mini-css-extract-plugin')
- const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin') //压缩 css
-
- module.exports = {
- entry: './src/js/index.js', // 由cmd执行目录决定
- output: {
- path: path.resolve(__dirname, '../dist'), // 由当前文件所在位置和要生成的dist位置关系决定
- filename: 'js/bundle.js'
- },
- resolve: {
- //导入语句省略后缀
- extensions: ['.ts', '.js', '.json'],
- //导入路径的别名
- alias: {
- css: path.resolve(__dirname, './src/css')
- },
- //解析模块目录
- // modules: [path.resolve(__dirname, '../node_modules'), 'node_modules']
- },
- module: {
- rules: [
- {
- test: /\.less$/,
- use: [
- {
- loader: MiniCssExtractPlugin.loader,
- options: {
- publicPath: '../'
- }
- },
- 'css-loader',
- 'less-loader'
- ]
- },
- {
- test: /\.m?js$/,
- exclude: /(node_modules)/,
- use: {
- loader: 'babel-loader',
- options: {
- "presets": [
- ["@babel/preset-env", {
- useBuiltIns: "usage", //按需引入需要使用polyfill
- corejs: { version: 3 }, //解决不能找到core-js的问题
- targets: { //解决兼容性处理哪些浏览器
- "chrome": "58",
- "ie": "9"
- }
- }]
- ],
- "cacheDirectory": false // 开启babel缓存,只编译未编译代码,可减少编译时间
- }
- }
- },
- {
- test: /\.(png|jpg|gif|jpeg)$/,
- use: {
- loader: 'url-loader',
- options: {
- limit: 8192,
- outputPath: 'images',
- name: '[hash:5].[ext]'
- }
- }
- },
- {
- test: /\.(html)$/,
- use: {
- loader: 'html-loader'
- }
- },
- {
- test: /\.(eot|svg|woff|woff2|ttf|mp3|mp4)$/,
- use: [{
- loader: 'file-loader',
- options: {
- outputPath: 'media',
- name: '[hash:5].[ext]'
- }
- }]
- }
- ]
- },
- plugins: [new HtmlWebpackPlugin({
- template: "./src/index.html", // 以当前文件为模板创建新的html(1、结构和原来一样;2、会自动引入打包的资源),默认 ,路径由cmd执行目录决定
- filename: "index.html", // 打包后的index.html文件默认位于dist目录下
- minify: {
- removeComments: true, //去掉注释
- collapseWhitespace: true, //去掉空格
- removeRedundantAttributes: true,
- useShortDoctype: true,
- removeEmptyAttributes: true,
- removeStyleLinkTypeAttributes: true,
- keepClosingSlash: true,
- minifyJS: true,
- minifyCSS: true,
- minifyURLs: true,
- }
- }), new MiniCssExtractPlugin({
- filename: 'css/[name].css'
- }), new OptimizeCSSAssetsPlugin({
- cssProcessorPluginOptions: {
- preset: [
- 'default',
- {
- discardComments: {
- removeAll: true
- },
- },
- ]
- },
- cssProcessorOptions: {
- map: {
- inline: false,
- annotation: true
- }
- }
- })]
- }
- entry: './src/js/index.js', // 由cmd执行目录决定
- output: {
- path: path.resolve(__dirname, '../dist'), // 由当前文件(webpack.config.js)所在位置和要生成的dist位置关系决定
- filename: 'js/bundle.js'
- }
1、明确生成的dist目录结构,比如./dist/images、./dist/css、./dist/js、./dist/index.html,根据此目录结构来确定配置文件中配置项publicPath的路径。
如果是开发模式,则是./images、./css、./js、./index.html结构。
https://gitee.com/duansamve/webpack4-to-cli.githttps://gitee.com/duansamve/webpack4-to-cli.git
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。