Webpack学习笔记

    xiaoxiao2022-07-14  154

    webpack 学习笔记

    webpack学习笔记1 入门示例1.1 新建入门项目1.2 安装webpack和webpack-cli1.3 新建要通过webpack打包的文件1.4 使用webpack打包1.5 引用打包后的文件 2 基本知识2.1 关于执行`npx webpack`2.2 webpack基本配置2.2.1 配置输入输出2.2.2 配置模式 2.3 配置静态服务2.3.1 安装webpack-dev-server2.3.2 启动静态服务2.3.3 配置静态服务启动脚本2.3.4 配置具体静态服务配置 2.4 配置插件2.4.1 配置html-webpack-plugin插件 2.5 配置模块2.5.1 配置打包css2.5.2 配置使用less

    webpack学习笔记

    1 入门示例

    1.1 新建入门项目

    通过npm init命令新建一个项目:

    $ npm init -y npm init -y Wrote to /home/deepin/Desktop/doc/webpack/demo01/package.json: { "name": "demo01", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }

    1.2 安装webpack和webpack-cli

    通过npm install命令安装webpack和webpack-cli:

    npm install webpack webpack-cli --save-dev > webpack-cli@3.3.2 postinstall /home/deepin/Desktop/doc/webpack/demo01/node_modules/webpack-cli > node ./bin/opencollective.js Thanks for using Webpack! Please consider donating to our Open Collective to help us maintain this package. Donate: https://opencollective.com/webpack/donate npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN demo01@1.0.0 No description npm WARN demo01@1.0.0 No repository field. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) + webpack-cli@3.3.2 + webpack@4.32.2 added 390 packages from 217 contributors and audited 5231 packages in 65.573s found 0 vulnerabilities

    这里要注意的是,我是通过在项目中安装的方式来安装webpack的,而不是全局安装,这样的好处就是我们在每次执行webpack命令时都是以项目中的webapck版本为主。

    1.3 新建要通过webpack打包的文件

    webpack默认打包的文件是./src/index.js,所以我们在项目根目录新建一个src目录,并在src目录下新建一个index.js文件:

    import Hello from './hello' alert("hello webpack...") new Hello()

    上面index.js中引入了hello.js,所以index.js所在目录下新建一个index.js文件:

    export default function Hello() { console.log('hello ...') }

    1.4 使用webpack打包

    在项目根目录执行npx webpack命令:

    $ npx webpack Hash: 9f774ffb74e02491827e Version: webpack 4.32.2 Time: 184ms Built at: 2019-05-23 19:40:09 Asset Size Chunks Chunk Names main.js 955 bytes 0 [emitted] main Entrypoint main = main.js [0] ./src/index.js 25 bytes {0} [built] WARNING in configuration The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment. You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

    命令执行完后会在当前项目下生成dist/main.js。main.js就是我们打包后的文件了。

    1.5 引用打包后的文件

    在项目目录下新建一个index.html文件,引入main.js:

    <!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> <!-- 引用打包文件 --> <script src="./dist/main.js"></script> </body> </html>

    完成上述所有操作后,在浏览器中执行该html文件,就会发现js文件中的代码被执行了。

    2 基本知识

    2.1 关于执行npx webpack

    如果我们在命令行中只是执行了webpack命令,那么程序会去查找系统中安装的webpack,也就是全局安装的webpack,由于我们是局部安装的 webpack,所以通过npx命令就能执行项目中的webpack命令,即程序会找当前项目下的./node_modules/.bin/webpack执行,而执行webpack命令又需要webpack-cli,所以也要安装webpack-cli。

    2.2 webpack基本配置

    2.2.1 配置输入输出

    由示例程序我们知道webpack默认打包项目目录下的./src/index.js文件,打包后的输出文件是./dist/main.js。那么我们如果想修改配置要怎么做呢?webpack的默认配置文件一般是webpack.config.js,我们在项目目录下新建一个webpack.config.js,并键入如下内容:

    const path = require('path') module.exports = { // 指定输入文件 entry: './src/access.js', // 指定输出文件 output: { // 输出文件的文件名 filename: 'bundle.js', // 输出文件路径 path: path.resolve(__dirname, "build") } }

    重新执行webpack打包命令,我们将会看到在项目根目录生成一个build/bundle.js。我们在index.html中引入该文件,并在浏览器中执行,我们会发现access.js被执行了。

    2.2.2 配置模式

    我们打开打包后的文件可以看到打包的文件是被压缩了的,我们也可以在配置文件中配置mode属性配置来指定打包是否压缩:

    const path = require('path') module.exports = { // 配置模式 mode: 'production', // 指定输入文件 entry: './src/access.js', // 指定输出文件 output: { // 输出文件的文件名 filename: 'bundle.js', // 输出文件路径 path: path.resolve(__dirname, "build") } } development:会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。production:会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin.none:没有应用任何插件

    2.3 配置静态服务

    2.3.1 安装webpack-dev-server

    webpack-dev-server提供了静态服务能力,我们通过npm来安装:

    npm install webpack-dev-server -D

    2.3.2 启动静态服务

    通过执行webpack-dev-server命令就可以启动服务:

    $ npx webpack-dev-server ℹ 「wds」: Project is running at http://localhost:8081/ ℹ 「wds」: webpack output is served from / ℹ 「wds」: Content not from webpack is served from /home/deepin/Desktop/doc/webpack/demo01 ℹ 「wdm」: Hash: ee964693b814a03fffa1 Version: webpack 4.32.2 Time: 271ms Built at: 2019-05-24 15:32:31 Asset Size Chunks Chunk Names bundle.js 349 KiB main [emitted] main Entrypoint main = bundle.js [0] multi (webpack)-dev-server/client?http://localhost ./src/access.js 40 bytes {main} [built] [./node_modules/ansi-html/index.js] 4.16 KiB {main} [built] [./node_modules/events/events.js] 13.3 KiB {main} [built] [./node_modules/html-entities/index.js] 231 bytes {main} [built] [./node_modules/loglevel/lib/loglevel.js] 7.68 KiB {main} [built] [./node_modules/node-libs-browser/node_modules/punycode/punycode.js] 14.3 KiB {main} [built] [./node_modules/querystring-es3/index.js] 127 bytes {main} [built] [./node_modules/url/url.js] 22.8 KiB {main} [built] [./node_modules/webpack-dev-server/client/index.js?http://localhost] (webpack)-dev-server/client?http://localhost 9.26 KiB {main} [built] [./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.59 KiB {main} [built] [./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.05 KiB {main} [built] [./node_modules/webpack-dev-server/node_modules/strip-ansi/index.js] (webpack)-dev-server/node_modules/strip-ansi/index.js 161 bytes {main} [built] [./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built] [./node_modules/webpack/hot/emitter.js] (webpack)/hot/emitter.js 75 bytes {main} [built] [./src/access.js] 18 bytes {main} [built] + 11 hidden modules ℹ 「wdm」: Compiled successfully.

    从打印的日志中我们可以看到服务已经在http://localhost:8081/端口启动了,在浏览器中访问该地址,就能访问到项目根目录。(注:如果项目根目录有index.html文件,会访问该文件,否则否此目录)。

    2.3.3 配置静态服务启动脚本

    我们每次启动静态服务器时都要输入npx webpack-dev-server来启动,我们也可以自定义指定启动,类似开vue中的npm run serve,我们在package.json的scripts字段中配置"serve": "webpack-dev-server":

    { "name": "demo01", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", // 这里是我们配置的静态服务器 "serve": "webpack-dev-server" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "webpack": "^4.32.2", "webpack-cli": "^3.3.2", "webpack-dev-server": "^3.4.1" } }

    配置好后,我们可以通过执行npm run serve来启动静态服务。同样的我们在执行webpack打包的时候执行的是npx webpack,我们也能配置成npm run build来执行打包, 如下 :

    { "name": "demo01", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "serve": "webpack-dev-server", // 配置webpack 打包 "build": "webpack" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "webpack": "^4.32.2", "webpack-cli": "^3.3.2", "webpack-dev-server": "^3.4.1" } }

    注:webpack.config.js是webpack默认的配置文件名字,我们可以通过在执行webpack命令时指定使用哪个配置文件,如npx webpack --config my.config.js。

    2.3.4 配置具体静态服务配置

    我们可以在webpack.config.js(webpack配置文件中)添加devServer属性来配置静态服务器:

    const path = require('path') module.exports = { devServer: { // 指定启动端口 port: 9000, // 启动时添加进度条 progress: true, // 静态服务访问根目录 contentBase: './html/', // 采用gzip压缩 compress: true }, mode: 'production', // 指定输入文件 entry: './src/access.js', // 指定输出文件 output: { // 输出文件的文件名 filename: 'bundle.js', // 输出文件路径 path: path.resolve(__dirname, "build") } }

    我们看一下这个目录contentBase: './html/',,这个目录就是配置的当我们访问服务端口时,会访问这个目录下的index.html文件,如果不配置这个目录的话默认访问的就是项目根目录下的index.html文件。

    2.4 配置插件

    2.4.1 配置html-webpack-plugin插件

    安装插件npm install $ npm installl html-webpack-plugin -D 配置 插件在plugins字段中配置,template属性指定要配置的html模块文件(要被打包的html文件),该文件会被自动引入打包后的.js文件,filename字段指定打包后的html文件的名字。 const path = require('path') let HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { devServer: { // 指定启动商品 port: 9000, // 启动时添加进度条 progress: true, // 静态服务访问根目录 contentBase: './html/', // 采用gzip压缩 compress: true }, mode: 'production', // 指定输入文件 entry: './src/access.js', // 指定输出文件 output: { // 输出文件的文件名 filename: 'bundle.js', // 输出文件路径 path: path.resolve(__dirname, "build") }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html' }) ] }

    注意:contentBase: './html/',我们指定了静态服务器的默认访问路径是./thml/目录,但是静态服务会优先访问HtmlWebpackPlugin打包后的目录(注:这个目录在运行npx webpack-dev-server时并没有生成)。为了更好的理解,请看下面所示:

    -项目根目录 - html - index.html - test.html - build - index.html - bundle.js - test.html

    项目有如下目录,我们通过启动npx wepack-dev-server并在浏览器中访问启动项目(假设项目端口为8000),也就是localhost:8000会访问到build/index.html,如果访问localhost:8000/bundle.js会访问到build/bundle.js,如果访问localhost:8000/test.html会访问到html/test.html,也就是说服务优先访问打包目录中文件。 我们更改一下项目中的内容,删除html/test.html,即:

    -项目根目录 - html - index.html - build - index.html - bundle.js - test.html

    我们再访问localhost:8000/test.html就访问不到了,说明我们访问的不是打包后生成的目录,为了验证我们的说法,我们删除build目录:

    - html - index.html

    我们启动项目,我们同样做前面所示的各种访问。

    更多配置 // 要导入. const HtmlWebpackPlugin = require('html-webpack-plugin') plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'main.html', minify: { // 除去打包后的html中的双引号操作 removeAttributeuotes: true, // 除去打包后的html中的空白符 collapseWhitespace: true }, // 打包后的html文件引入的打包的js后面加上hash串 hash: true }) ]

    补充:我们也可以在打包生成的.js文件名中生成hash,如下 我们在打包生成的js文件名中生成了一个截取8个字符长度的hash串(就像这样:bundle.4bf4c7f9.js):

    output: { // 输出文件的文件名 filename: 'bundle.[hash:8].js', // 输出文件路径 path: path.resolve(__dirname, "build") },

    2.5 配置模块

    webapck默认只支持js打包,如果想要配置css等其他模块的打包需要配置模块对应的loader来实现。对于各个loader的配置,是在webpack的配置文件中的module/rules属性中配置的,如下:

    module.exports = { module: { rules: [ ] } }

    2.5.1 配置打包css

    这里用一个新的项目作演示(npm init)。

    安装html-webpack-plugin npm install html-webpack-plugin -D 配置html-webpack-plugin const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { plugins : [ new HtmlWebpackPlugin({ template: './src/index.html' }) ] } 新建main.css: @import './color.css'; body { background: gray; } 新建color.css body { color: whitesmoke; } 安装css-loader css-loader用于解析css语法并打包css文件,通过npm安装css-loaer: $ npm install css-loader -D 安装style-loader style-loader用来把css文件插入到html文件的header标签中,安装: $ npm install style-loader -D 配置css-loader和style-loader: const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { plugins : [ new HtmlWebpackPlugin({ template: './src/index.html' }) ], module: { // 在这下面配置loder rules: [ // 配置loader使用规则 { test: /\.css$/, // loader 要应用到哪些文件上,接收正则表达式 use: ["style-loader","css-loader"] // 要应用的loader,注意是从后向前执行,先解析css再插入css } ] } } 新建index.js和index.html 在src下新建index.js并引入main.css: import './main.css'

    在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> hello world! </body> </html> 执行npx webpack打包 执行命令npx webpack打包,会在dist目录下生成main.js和index.html两个文件,并在浏览器中运行index.html,会看到index.html中的header中的样式部分如下(浏览器中,不是打包生成的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> <style type="text/css">body { color: whitesmoke; }</style><style type="text/css">body { background: black; }</style></head> <body> hello world! <script type="text/javascript" src="main.js"></script> </body></html> 补充 由于css样式会被插入到html文件的header末尾,所以自己在html中写的样式会被覆盖,如果想要应用上自己写的样式,就然css样式插入到最前面: module: { rules: [ { test: /\.css$/, use: [ // 对象语法 { loader: "style-loader", options: { // 插入到顶部 insertAt: "top" } }, "css-loader" ] } ] }

    2.5.2 配置使用less

    修改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> <style type="text/css"> body { background: deeppink; } </style> </head> <body> hello world! <div id="ls"> </div> </body> </html> 新建style.less文件 body { #ls { width: 100px; height: 100px; border: 2px solid white; } } 在index.js中引入style.less import "./main.css"; // 引入 less 使用import 和 require都可以 require("./style.less") 安装less和less-loader npm install less less-loader -D 配置less module: { rules: [ { test: /\.css$/, use: [ { loader: "style-loader", options: { // 插入到顶部 insertAt: "top" } }, "css-loader" ] }, // 对less文件的配置 { // 配置处理less文件 test: /\.less$/, // 从后向前执行 先执行 less-loader 再执行 css-loader 最后执行 css-loader use: ['style-loader', 'css-loader', 'less-loader'] } ] }
    最新回复(0)