Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack学习总结 #15

Open
HuoXiaoYe opened this issue Jul 2, 2019 · 0 comments
Open

webpack学习总结 #15

HuoXiaoYe opened this issue Jul 2, 2019 · 0 comments

Comments

@HuoXiaoYe
Copy link

HuoXiaoYe commented Jul 2, 2019

写在前面

使用Webpack有一段时间了,但是感觉之前学的用的都比较零散,
所以在这里整理一下Webpack的使用知识,从一开始的入门到进阶。

你知道如何使用webpack打包项目吗?
你知道如何在React中使用模块化的css样式吗?

学完文本文章后,嘿嘿嘿....

什么是webpack?

webpack 是前端的一个项目构建工具,它是基于 Node.js 开发出来的一个前端工具;
当我们在项目中导入了过多的外部文件是,或造成请求过程慢,错综复杂的依赖关系,以及全局变量污染等问题
那么,如何解决这些问题呢?请使用webpack
webpack 这个前端自动化构建工具,可以完美实现资源的合并、打包、压缩、混淆等诸多功能。

webpack安装的两种方式

  1. 运行npm i webpack -g全局安装webpack,这样就能在全局使用webpack的命令
  2. 在项目根目录中运行npm i webpack --save-dev 将webpack安装到项目依赖中

初步使用webpack打包构建列表隔行变色案例

  1. 运行npm init初始化项目,使用npm管理项目中的依赖包
  2. 创建项目基本的目录结构
  3. 使用cnpm i jquery --save安装jquery类库
  4. 创建main.js并书写各行变色的代码逻辑:
	// 导入jquery类库
    import $ from 'jquery'

    // 设置偶数行背景色,索引从0开始,0是偶数
    $('#list li:even').css('backgroundColor','lightblue');
    // 设置奇数行背景色
    $('#list li:odd').css('backgroundColor',function(){
		return "#f60"
	});
  1. 直接在页面上引用main.js会报错,因为浏览器不认识import这种高级的JS语法,需要使用webpack进行处理,webpack默认会把这种高级的语法转换为低级的浏览器能识别的语法;
  2. ** webpack最基本的使用:**运行webpack 入口文件路径 输出文件路径main.js进行处理:
webpack src/js/main.js dist/bundle.js

** 我们每打包一次就要输入一长串的的指令,那么有没有什么办法可以简单实现打包呢,请往下看 **

使用webpack的配置文件简化打包时候的命令

  1. 在项目根目录中创建webpack.config.js
  2. 由于运行webpack命令的时候,webpack需要指定入口文件和输出文件的路径,所以,我们需要在webpack.config.js中配置这两个路径:
    // 导入处理路径的模块
    var path = require('path');

    // 导出一个配置对象,将来webpack在启动的时候,会默认来查找webpack.config.js,并读取这个文件中导出的配置对象,来进行打包处理
    module.exports = {
        entry: path.resolve(__dirname, 'src/js/main.js'), // 项目入口文件
        output: { // 配置输出选项
            path: path.resolve(__dirname, 'dist'), // 配置输出的路径
            filename: 'bundle.js' // 配置输出的文件名
        }
    }
  1. 这样,我们在打包的时候,输入当我们在控制台直接输入 webpack 命令执行的时候,webpack会执行以下步骤
  • 首先,webpack 发现,我们并没有通过命令的形式,给它指定入口和出口
  • webpack 就会去 项目的 根目录中,查找一个叫做 webpack.config.js 的配置文件
  • 当找到配置文件后,webpack 会去解析执行这个 配置文件,当解析执行完配置文件后,就得到了 配置文件中,导出的配置对象
  • 当 webpack 拿到 配置对象后,就拿到了 配置对象中,指定的 入口 和 出口,然后进行打包构建;

** 我们想要解放自己的双手,可不可以我们在 ctrl + s的时候,自动打包呢?**

实现webpack的实时打包构建

  1. 使用webpack-dev-server来实现代码实时打包编译,当修改代码之后,会自动进行打包构建。
  2. 运行cnpm i webpack-dev-server --save-dev安装到开发依赖
  3. 安装完成之后,在命令行直接运行webpack-dev-server来进行打包,发现报错,此时需要借助于package.json文件中的指令,
    来进行运行webpack-dev-server命令,在scripts节点下新增"dev": "webpack-dev-server"指令,
    发现可以进行实时打包,但是dist目录下并没有生成bundle.js文件,这是为什么呢?因为webpack-dev-server将打包好的文件放在了内存中
  • bundle.js放在内存中的好处是:由于需要实时打包编译,所以放在内存中速度会非常快
  • 这个时候我们访问webpack-dev-server启动的http://localhost:8080/网站,发现是一个文件夹的面板,需要点击到src目录下,才能打开我们的index首页,
    此时引用不到bundle.js文件,需要修改index.html中script的src属性为:<script src="../bundle.js"></script>
  • 为了能在访问http://localhost:8080/的时候直接访问到index首页,可以使用--contentBase src指令来修改dev指令,指定启动的根目录:
"dev": "webpack-dev-server --contentBase src"

同时修改index页面中script的src属性为<script src="bundle.js"></script>

  1. 注意:由于最新的webpack和webpack-dev-server打包报错,这里我使用的是webpack@3.12.0和webpack-dev-server@2.9.3

使用html-webpack-plugin插件配置启动页面

由于使用--contentBase指令的过程比较繁琐,需要指定启动的目录,同时还需要修改index.html中script标签的src属性,所以推荐大家使用html-webpack-plugin插件配置启动页面.

html-webpack-plugin的两个作用

  • 自动在内存中根据指定页面生成一个内存的页面
  • 自动,把打包好的(output输出的) bundle.js 追加到页面中去

使用步骤

  1. 运行cnpm i html-webpack-plugin --save-dev安装到开发依赖
  2. 修改webpack.config.js配置文件如下:
    // 导入处理路径的模块
    var path = require('path');
    // 导入自动生成HTMl文件的插件
    var htmlWebpackPlugin = require('html-webpack-plugin');

    module.exports = {
        entry: path.resolve(__dirname, 'src/js/main.js'), // 项目入口文件
        output: { // 配置输出选项
            path: path.resolve(__dirname, 'dist'), // 配置输出的路径
            filename: 'bundle.js' // 配置输出的文件名
        },
        plugins:[ // 添加plugins节点配置插件
            new htmlWebpackPlugin({
                template:path.resolve(__dirname, 'src/index.html'),//模板路径
                filename:'index.html'//自动生成的HTML文件的名称
            })
        ]
    }
  1. 修改package.jsonscript节点中的dev指令如下:
"dev": "webpack-dev-server"
  1. 将index.html中script标签注释掉,因为html-webpack-plugin插件会自动把bundle.js注入到index.html页面中!

实现自动打开浏览器、热更新和配置浏览器的默认端口号

注意:热更新在JS中表现的不明显,在CSS身上表现明显!

方式1:

  • 修改package.json的script节点如下,其中--open表示自动打开浏览器,--port 4321表示打开的端口号为4321,--hot表示启用浏览器热更新:
"dev": "webpack-dev-server --hot --port 4321 --open"

方式2:

  1. 修改webpack.config.js文件,新增devServer节点如下:
 devServer: { // 这是配置 dev-server 命令参数的第二种方法,相对来说,这种方法麻烦一些
    open: true, // 自动打开浏览器
    port: 3000, // 设置启动时候的运行端口
    contentBase: 'src', // 指定托管的根目录
    hot: true
  },
  1. 在头部引入webpack模块:
var webpack = require('webpack');
  1. plugins节点下新增:
new webpack.HotModuleReplacementPlugin()

使用webpaack处理css文件和高级js语法

webpack 处理第三方文件类型的过程:

  1. 发现这个 要处理的文件不是JS文件,然后就去 配置文件中,查找有没有对应的第三方 loader 规则
  2. 如果能找到对应的规则, 就会调用 对应的 loader 处理 这种文件类型;
  3. 在调用loader 的时候,是从后往前调用的;
  4. 当最后的一个 loader 调用完毕,会把 处理的结果,直接交给 webpack 进行 打包合并,最终输出到 bundle.js 中去

使用webpack打包css文件

  1. 运行cnpm i style-loader css-loader --save-dev
  2. 修改webpack.config.js这个配置文件:
module: { // 用来配置第三方loader模块的
        rules: [ // 文件的匹配规则
            { test: /\.css$/, use: ['style-loader', 'css-loader'] }//处理css文件的规则
        ]
    }
  1. 注意:use表示使用哪些模块来处理test所匹配到的文件;use中相关loader模块的调用顺序是从后向前调用的;

使用webpack打包less文件

  1. 运行cnpm i less-loader less -D
  2. 修改webpack.config.js这个配置文件:
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },

使用webpack打包sass文件

  1. 运行cnpm i sass-loader node-sass --save-dev
  2. webpack.config.js中添加处理sass文件的loader模块:
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }

使用webpack处理css中的路径

  1. 运行cnpm i url-loader file-loader --save-dev
  2. webpack.config.js中添加处理url路径的loader模块:
{ test: /\.(png|jpg|gif)$/, use: 'url-loader' }
  1. 可以通过limit指定进行base64编码的图片大小;只有小于指定字节(byte)的图片才会进行base64编码:
{ test: /\.(png|jpg|gif)$/, use: 'url-loader?limit=43960' },

使用babel处理高级JS语法

  1. 运行cnpm i babel-core babel-loader babel-plugin-transform-runtime --save-dev安装babel的相关loader包
  2. 运行cnpm i babel-preset-es2015 babel-preset-stage-0 --save-dev安装babel转换的语法
  3. webpack.config.js中添加相关loader模块,其中需要注意的是,一定要把node_modules文件夹添加到排除项:
{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }
  1. 在项目根目录中添加.babelrc文件,并修改这个配置文件如下:
{
    "presets":["es2015", "stage-0"],
    "plugins":["transform-runtime"]
}
  1. 注意:语法插件babel-preset-es2015可以更新为babel-preset-env,它包含了所有的ES相关的语法;

在React中使用模块化的css

写在最后,学过vue的同学都知道,我们可以在 <style scoped="scoped"></style> 来设置局部的css样式
那么,在react中如何实现局部的css样式呢?

  1. 在webpack.config.js中为css-loader启用模块化: css-loader?modules&localIdentName=[name]_[local]-[hash:8]
  2. 在js 文件中引入样式
	import indexStyle from 'Index.css'`
	// 此时 indexStyle 是一个对象,
	// indexStyle = {
	//	title : '乱码1',
		box : '乱码2'......
	// }
	export default function App(props) {
			return (
				<div className={indexStyle.box}>
				  <h1 className={indexStyle.title}>XXXXXX</h1>
				  <h3 className={indexStyle.body}>XXXXXX</h3>
				</div>
			)
	}

注意

/* 注意:当启用 CSS 模块化之后,这里所有的类名,都是私有的,
	如果想要把类名设置成全局的一个类,可以把这个类名,用 :global() 给包裹起来 */
/* 当使用 :global() 设置了全局的 类样式之后,这个类不会被重命名 */
/* 只有私有的类才会被重命名 */

:global(.title){
  color:red;
  text-align: center;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant