博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
webpack4x,走你...
阅读量:6485 次
发布时间:2019-06-23

本文共 11991 字,大约阅读时间需要 39 分钟。

webpack已经是前端开发必不可少的神器了;

一、#先看看他的核心功能,为什么用他?#

1.打包:可以把多个Javascript文件打包成一个文件,减少服务器压力和下载带宽。

2.转换:把拓展语言转换成为普通的JavaScript,让浏览器顺利运行。

3.优化:前端变的越来越复杂后,性能也会遇到问题,而WebPack也开始肩负起了优化和提升性能的责任。

4.Webpack在生产环境中有一个重要的作用就是减少http的请求数

以上三点即是它=他的核心作用。

二、webpack(当下最新版4.8.3)安装及环境配置

webpack这家伙更新甚快,所以不同版本的webpack所使用的命令也几乎各不相同

1.全局安装webpack npm i webpack -g

2.进入项目文件夹,初始化项目,为了生成pake.json文件;npm init 持续回车即可

3.安装webpack的依赖node_modules; npm i -D webpack

4.全局安装webpack-cli;npm i webpack-cli -g

5.设置默认开发环境,设置mode(模式),指定是“开发环境(production)”还是“生产环境(development)”; 当然在持续开发中,得优先设置开发环境;webpack --mode development;

6.以后打包即可输入webpack --mode development;但是明显每次这样输入繁琐至极; 在pake.json文中的script下配置 "dev":"webpack --mode development" 和 "build":"webpack --mode production";

输入npm run dev即可打包到项目自动生成的dist文件夹中;npm run build打包生产环境;

7.所有的开发文件必须在src文件夹下,因为webpack4默认的入口文件夹就是src;

注意:

1、webpack-cli必须要全局安装,否则不能使用webpack指令;

2、webpack也必须要全局安装,否则也不能使用webpack指令。

3、webpack4.x中webpack.config.js这样的配置文件不是必须的。

4、默认入口文件是./src/index.js,默认输出文件./dist/main.js。

三、配置webpack.config.js| webpack-cli init

Will your application have multiple bundles? No // 单入口 string, 多页面 object2. Which module will be the first to enter the application? [example: './src/index'] ./src/index // 程序入口3. What is the location of "app"? [example: "./src/app"] './src/index' // 程序主文件4. Which folder will your generated bundles be in? [default: dist]: // 输出目录,默认 dist5. Are you going to use this in production? No // (Yes 第9步默认'config', No 则为 'prod')6. Will you be using ES2015? Yes // 会添加 ES6 => ES5 的配置7. Will you use one of the below CSS solutions? CSS // 选一种样式语言,会生成对应的 loader 配置8. If you want to bundle your CSS files, what will you name the bundle? (press enter to skip) // 回车跳过9. Name your 'webpack.[name].js?' [default: 'config']: // webpack.config.jsCongratulations! Your new webpack configuration file has been created!复制代码

webpack.config.js一览

// 从依赖中引入pathconst path = require('path');const uglify = require('uglifyjs-webpack-plugin');//JS压缩插件,简称uglifyconst htmlPlugin= require('html-webpack-plugin');//html打包// const extractTextPlugin = require('exrract-text-plugin');//extract-text-webpack-plugin将CSS文件分离出来// __dirname是node.js的全局变量,它指向当前执行脚本所在的目录。var website = {  publicPath:"http://localhost:5252/"}module.exports = {    devtool: 'eval-source-map',    // entry:__dirname + '/src/main.js',    entry:{       main:'./src/main.js'    },    output:{      //打包的路径文件夹      path:path.resolve(__dirname,'dist'),//__dirname 表示当前文件所在的目录的绝对路径,path.resolve()方法将一系列路径或路径段解析为绝对路径      //或者这样写      // filename:'[name].js'//filename:是打包后的文件名称      // filename:'[name].[chunkHash:2].js'//每次打包都会引入最新的.js,防止浏览器缓存    },    //模块:例如解读CSS,图片如何转换,压缩    module:{      rules: [        {          test: /\.css$/,          use: ['style-loader', 'css-loader']           //或者loader: [ 'style-loader', 'css-loader' ]          //或者:use:[            // {loader:'style-loader'},            // {loader:'css-loader'}          // ]                  },        {          test:/\.(png|jpg|gif)/,          use:[{              loader:'url-loader',              options:{                  limit:500000              }          }]       }      ]    },    //插件,用于生产模版和各项功能    plugins:[      new uglify(),      new htmlPlugin({        minify:{            removeAttributeQuotes:true        },        hash:true,        template:'./src/index.html'           })    // new extractTextPlugin("./css/index.css")//配置分离后的路劲    ],    mode:'development',    //配置webpack开发服务功能    devServer: {      //设置基本目录结构      contentBase: "./dist",//本地服务器所加载的页面所在的目录 || contentBase:path:path.resolve(__dirname,'dist')      //服务器的IP地址,可以使用IP也可以使用localhost      host:'localhost',      //服务端压缩是否开启      compress:true,      //配置服务端口号      port:5252,      historyApiFallback: true,//不跳转      inline: true//实时刷新    }   }  复制代码

三、webpack:服务和热更新

安装服务npm install webpack-dev-server –save-dev 并在page.json中 设置 scripts": { "server":"webpack-dev-server" },

热更新:webpack-dev-server 提供了两种模式用于自动刷新页面: npm run server; npm start使用此命令在pake.json中scrpts中设置: "start": "webpack && webpack-dev-server --hot --inline"

三、loaders(webpack的核心):

所有的Loaders都需要在npm中单独进行安装,并在webpack.config.js里进行配置

1.Loaders的配置型:

test:用于匹配处理文件的扩展名的表达式,这个选项是必须进行配置的;

use:loader名称,就是你要使用模块的名称,这个选项也必须进行配置,否则报错

include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);

query:为loaders提供额外的设置选项(可选)。

四、文件压缩打包 1.css文件压缩,可以在入口文件index.js中导入,将其压缩到dist下的js文件中;

index.js 写入 import css from '.././css/index.css'

2.css中的图片路劲问题:

很显然,打包后的图片是404; 所以解决方法是要安装url-loader 和 file-loader;

npm install --save-dev file-loader url-loader


file-loader:解决引用路径的问题,拿background样式用url引入背景图来说,我们都知道,webpack最终会将各个模块打包成一个文件,因此我们样式中的url路径是相对入口html页面的,而不是相对于原始css文件所在的路径的。这就会导致图片引入失败。这个问题是用file-loader解决的,file-loader可以解析项目中的url引入(不仅限于css),根据我们的配置,将图片拷贝到相应的路径,再根据我们的配置,修改打包后文件引用路径,使之指向正确的文件。

url-loader:如果图片较多,会发很多http请求,会降低页面性能。这个问题可以通过url-loader解决。url-loader会将引入的图片编码,生成dataURl。相当于把图片数据翻译成一串字符。再把这串字符打包到文件中,最终只需要引入这个文件就能访问图片了。当然,如果图片较大,编码会消耗性能。因此url-loader提供了一个limit参数,小于limit字节的文件会被转为DataURl,大于limit的还会使用file-loader进行copy。


url-loader封装了file-loader。url-loader不依赖于file-loader,即使用url-loader时,只需要安装url-loader即可,不需要安装file-loader,因为url-loader内置了file-loader。

3.css文件分离

安装extractTextPlugin; npm install extract-text-webpack-plugin@next --save-dev;

const extractTextPlugin = require("extract-text-webpack-plugin");

**注意:**最新版的webpack要安装对应升级版的分离插件,所以要加上@next;

安装完在webpack.config.js中引入::const extractTextPlugin = require('extract-text-webpack-plugin');

安装完之后,还得在webpack.config.js中设置加载项:

// use: [        //   { loader: 'style-loader', options: { sourceMap: true } },        //   { loader: 'css-loader' }        // ]        // css分离:        替换上面的如下:::        use: extractTextPlugin.extract({          fallback: "style-loader",          use: "css-loader"        })复制代码

设置Plugins: new extractTextPlugin('/css/index.css')设置打包后的文件路劲

npm run dev后可以看见dist文件夹下自动生成css;

4.css文件分离后,会导致css中的背景图片路劲不对;

解决方式是: 在webpack.conifg.js中全局声明一个ip属性:

var website ={  publicPath:"http://localhost:5200/"//你的本机ip地址,或自定义的server端口}然后再output(输出对象)中,调用全局变量设置的属性publicPath;实际是改其相对路径为绝对路劲publicPath:website.publicPath在进行打包即可找对路劲复制代码

5.处理html中的图片:路劲及文件打包

安装到生产环境中:npm install html-withimg-loader --save在webpack.config.js中配置loader:{    test: /\.(htm|html)$/i,     use:[ 'html-withimg-loader'] }然后进行打包,可以发现图片路劲正确,并被打包复制代码

6.less文件打包::: 安装less和less-loader npm i less less-loader -D

首先:在src目录下新建less文件;次之,在入口文件js中引入less文件;import less from '.././less/index.less';然后再webpack.config.js中配置less-loader:use: [            {loader:'css-loader'},            {loader:'less-loader'} //在js中分离less文件到css中;          ]复制代码

7.jslabel转换::: cnpm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react

在webpack.config.js 中配置bable{    test:/\.(jsx|js)$/,    use:{        loader:'babel-loader',        options:{            presets:[                "es2015","react"            ]        }    },    exclude:/node_modules/}复制代码

现在网络上已经不流行babel-preset-es2015,现在官方推荐使用的是babel-preset-env,

npm install --save-dev babel-preset-env

新建.babelrc文件,在里面的配置即可

{    "presets":["react","env"]}复制代码

基本的最终webpack.config.js配置

// 在webpack.config.js里引入必须使用require,否则会报错的;const webpack = require('webpack');//引入webpack自带的插件包,在plugins中调用即可const path = require('path');//引入node的path模块(node的path 模块提供了一些用于处理文件路径的小工具)const UglifyJSPlugin = require('uglifyjs-webpack-plugin');//此乃压缩JS的插件,简称uglifyconst HtmlWebpackPlugin = require('html-webpack-plugin');//此乃压缩html的插件const extractTextPlugin = require('extract-text-webpack-plugin');//之前将css文件打包到了js文件中,没有将其分离出来,所以用此插件可以单独提取css和lessconst glob = require('glob');//引入Node.js 中的全局对象是 global;node的glob模块允许你使用*等符号,来写一个glob规则;https://blog.csdn.net/tangxiaolang101/article/details/53931145const PurifyCSSPlugin = require('purifycss-webpack');//PurifyCSS插件可以大大减少CSS冗余// const entry = require(./webpack_config/entry_webpack.js);// 处理css文件图片路劲问题var website ={  publicPath:"http://localhost:5200/"}// if(process.env.type== "build"){//   var website={  //       publicPath:"http://localhost:5200/"//   }// }else{//   var website={//       publicPath:"http://localhost:5200/"//   }// }// console.log( encodeURIComponent(process.env.type));module.exports = {  devtool: 'eval-source-map',  entry: {    main:'./src/js/index.js'  },  // entry:entry.path,  output: {    filename: '[name].bundle.js',    path: path.resolve(__dirname, 'dist'),    publicPath:website.publicPath// 处理css文件图片路劲问题 调用全局变量设置的属性publicPath;实际是改其相对路径为绝对路劲  },  module: {    rules: [      {        test: /\.js$/,        exclude: /node_modules/,        loader: 'babel-loader',        options: {          presets: ['env']        }      },      {        test: /\.css$/,        // use: [        //   { loader: 'style-loader', options: { sourceMap: true } },        //   { loader: 'css-loader' }        // ]        // css分离:        use: extractTextPlugin.extract({          use: [            {loader:'css-loader'},            {loader:'less-loader'}          ],          fallback: "style-loader",        })      },      {        test:/\.(png|jpg|gif)/ ,        use:[{            loader:'url-loader',            options:{                limit:5000,                outputPath:'img/'//outputPath属性表示输出打包后的文件路劲             }        }]     },    //  配置解决html中的 img标签图片路劲404问题     {      test: /\.(htm|html)$/i,       use:[ 'html-withimg-loader']   },  {    test: /\.less$/,  use: [    {loader: 'style-loader'},    {loader:'css-loader'},    {loader:'less-loader'}  ]  },  {    test:/\.(jsx|js)$/,    use:{        loader:'babel-loader',        options:{            presets:[                "es2015","react"            ]        }    },    exclude:/node_modules/},{       test:/\.(jsx|js)$/,    use:{        loader:'babel-loader',    },    exclude:/node_modules/}  //  {  //   watchOptions:{   //     //检测修改的时间,以毫秒为单位  //     poll:1000,   //     //防止重复保存而发生重复编译错误。这里设置的500是半秒内重复保存,不进行打包操作  //     aggregateTimeout:500,   //     //不监听的目录  //     ignored:/node_modules/,   // }  //  }    ]  },  plugins: [    new UglifyJSPlugin(),    new extractTextPlugin('/css/index.css'),    new HtmlWebpackPlugin({        minify:{            removeAttributeQuotes:true          },        hash:true,        template:'./src/html/index.html',        filename:'html/index.html'    }),    new HtmlWebpackPlugin({      template:'./src/html/oop.html',      filename:'html/oop.html'    }),    new PurifyCSSPlugin({      // Give paths to parse for rules. These should be absolute!      paths: glob.sync(path.join(__dirname, 'src/*.html')), }),      // ProvidePlugin是webpack自带的插件,可以用此插件全局的引入所要使用的js库      new webpack.ProvidePlugin({ $:"jquery" })  ],  // 这款插件用于压缩 JS 代码,减少资源体积大小  devServer: {    //设置基本目录结构    contentBase: "./dist",//本地服务器所加载的页面所在的目录 || contentBase:path:path.resolve(__dirname,'dist')    //服务器的IP地址,可以使用IP也可以使用localhost    host:'localhost',    //服务端压缩是否开启    compress:true,    //配置服务端口号    port:5200,    historyApiFallback: true,//不跳转    inline: true//实时刷新  } };复制代码

pake.josn

{  "name": "md",  "version": "1.0.0",  "description": "",  "main": "index.js",  "scripts": {    "test": "echo \"Error: no test specified\" && exit 1",    "dv": "webpack --mode development",    "bd": "webpack --mode production",    "server": "webpack-dev-server  --open"  },  "author": "",  "license": "ISC",  "dependencies": {    "html-withimg-loader": "^0.1.16",    "jquery": "^3.3.1",    "npm": "^6.0.1",    "to": "^0.2.9",    "update": "^0.7.4"  },  "devDependencies": {    "autoprefixer": "^8.5.0",    "babel-core": "^6.26.3",    "babel-loader": "^7.1.4",    "babel-preset-env": "^1.7.0",    "babel-preset-es2015": "^6.24.1",    "babel-preset-react": "^6.24.1",    "css-loader": "^0.28.11",    "extract-text-webpack-plugin": "^4.0.0-beta.0",    "file-loader": "^1.1.11",    "html-webpack-plugin": "^3.2.0",    "less": "^3.0.4",    "less-loader": "^4.1.0",    "postcss-loader": "^2.1.5",    "purify-css": "^1.2.5",    "purifycss-webpack": "^0.7.0",    "style-loader": "^0.21.0",    "uglifyjs-webpack-plugin": "^1.2.5",    "url-loader": "^1.0.1",    "webpack": "^4.8.3",    "webpack-cli": "^2.1.3",    "webpack-dev-server": "^3.1.4"  }}复制代码
你可能感兴趣的文章
给网站更换服务器需要注意什么?
查看>>
成长型企业ERP系统实施的八大准则
查看>>
nginx重启脚本
查看>>
理解Linux系统/etc/init.d目录和/etc/rc.local脚本
查看>>
代码整洁之道
查看>>
svm 预测标签的概率输出
查看>>
SDK目录结构
查看>>
ActiveMQ(25):优化与建议
查看>>
使用Intelij Idea经过的坑
查看>>
微信 token
查看>>
【原创】JAVA通过过滤器防止脚本注入
查看>>
马哥linux第8周作业
查看>>
gnu autotools
查看>>
在AIX上增加文件系统空间
查看>>
svchost cpu占用率过高电脑卡死
查看>>
【中小企业经典案例分析一】基础架构描述
查看>>
Android进程间通信(IPC)机制Binder简要介绍和学习计划
查看>>
在git@osc上托管自己的代码
查看>>
Training的第五天
查看>>
软件架构师的职责范围谈
查看>>