# vue-webpack-nocli **Repository Path**: linwt0/vue-webpack-nocli ## Basic Information - **Project Name**: vue-webpack-nocli - **Description**: 不使用vuecli手脚架创建基于vue与webpack整合的项目 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-11-11 - **Last Updated**: 2024-11-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 【不使用vuecli手脚架创建基于vue与webpack整合的项目 笔记】 【一、项目初始化】 1、init初始化 使用npm init -y完成项目初始化,会生成package.json文件。 init:完成初始化 -y:使用默认选项目 package.json文件: { "name": "vue-webpack-nocli", "version": "1.0.0", "description": "不使用vuecli手脚架创建基于vue与webpack整合的项目", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" } 2、安装webpack 我们需要使用webpack来完成打包,因此需要安装webpack和webpack-cli。 在命令行中执行npm install webpack webpack-cli -D install:安装 -D:安装在开发环境依赖,是--save-dev的简写。 安装完成之后,在根目录生成node_modules问价和package-lock.json文件。 在package.json文件增加 "devDependencies" 属性和其值。 "devDependencies": { "webpack": "^5.33.2", "webpack-cli": "^4.6.0" } 【二、编写项目入口】 1、编写index.html 在项目根目录下创建一个index.html,作为项目主页文件,编写如下内容。 不使用vuecli手脚架创建基于vue与webpack整合的项目
2、编写vue根实例 创建src目录。在src目录下创建main.js作为项目的总入口文件。 在main.js中,完成如下操作。 1.创建 vue 根实例。 2.挂载App组件。 1)安装vue 执行npm install vue 注意这时候没使用到-D,说明在开发环境和生产环境都需要使用到vue。 安装完成之后在package.json文件增加"dependencies"属性和其值。 "dependencies": { "vue": "^2.6.12" } 2)创建Vue根实例 import Vue from 'vue' new Vue({ el:'#app', components:{ APP } }) 3)挂载App组件 step1 编写App.vue文件 step2 挂载到根实例 在main.js中完成如下操作 1.导入App组件对象 2.挂载到Vue根实例 //导入APP组件对象 import App from './App.vue' new Vue({ el:'#app', components:{ App } }) step3 使用App标签渲染 new Vue({ el:'#app', components:{ App }, template:'' // 使用App标签渲染 }) 3、在index.html引入main.js测试 在index.html引入main.js测试发现报错。 Uncaught SyntaxError: Cannot use import statement outside a module 浏览器是不认识import这些东西的,因此需要使用webpack完成打包 【三、webpack基本配置】 为了让浏览器能够正确的解析,我们需要在使用webpack将我们的源代码进行打包。 1.创建webpack配置文件。 在根目录下创建webpack配置文件webpack.config.js,编写最基本的配置。 2.编写webpack脚本 在package.json中配置脚本: "scripts": { "build": "webpack" } 3.测试,此时执行npm run build打包会报错,因为webpack没办法打包vue文件 【4.使用vue-loader打包vue文件】 1.安装 vue-loader、vue-template-compiler 安装命令 npm install -D vue-loader vue-template-compiler 安装完成之后发现vue-loader依赖css-loader,因此需要安装css-loader 2.安装css-loader 执行命令npm install -D css-loader 3.webpack配置 从vue-loader@15版本开始,vue-loader需要在webpack中添加一个插件 const VueLoaderPlugin = require('vue-loader/lib/plugin') module.exports = { //打包规则 module:{ rules:[{ test:/\.vue$/, //遇到与vue结尾的文件,使用vue-loader来打包 loader:'vue-loader' }] }, // 插件 plugins:[ new VueLoaderPlugin() ] } 4.配置完成之后就可以打包了,执行npm run build 执行之后发现提示需要制定打包模式 打包模式,development or production module.exports = { mode:'development' // development or production } 5.重新打包,这时候在根目录index.html中引入打包的文件:dist/bundle.js, 然后在浏览器打开发现报错: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build. Vue会打包生成三个文件: runtime only 的文件 vue.common.js (运行时) compiler only 的文件 compiler.js (编译时) runtime + compiler 的文件 vue.js 而默认导出的是vue.common.js,如何解决? 解决方法: 在webpack.config.js中,添加别名的配置 module.exports = { resolve:{ alias:{ 'vue':'vue/dist/vue.js' } } } 6.总结 1.webpack本身只能打包js文件,如果需要打包其他文件需要借助于loader插件 2.loader其实就是专门用于打包特定文件的处理程序 【五、其他常用的loader】 一般来说,一个前端项目除了js文件外,还有一些常用的文件,如 图片文件 css文件 对于这些文件,webpack都不会打包,需要我们安装对应的loader帮助weback打包 1.打包图片 1)file-loader file-loader 将一个文件中的 import/require() 解析为 url,并且将文件发送到输出文件夹。 安装命令:npm install --save-dev file-loader 安装完成之后在package.json中"devDependencies"增加值: "devDependencies":{ "file-loader": "^6.2.0" } 安装完成file-loader之后配置webpack.config.js中的打包规则 module.exports = { module:{ rules:[{ test:/\.(jpg|jpeg|png|svg)$/, // 以这些文件结尾的文件进行file-loader打包 loader:'file-loader', options:{ name:'[name].[ext]', outputPath:"images" // 将图片打包到dist/images中 } }] } } 认情况下,生成文件的文件名,是文件内容的哈希值,并会保留所引用资源的原始扩展名。 所以要更改一些配置: 【name】 options: { name: '[path][name].[ext]', }, 默认情况下,文件会按照你指定的路径和名称输出同一目录中,且会使用相同的 URI 路径来访问文件。 【outputPath】指定用来放置一个或多个目标文件的文件系统路径 options: { outputPath: 'images', // 将图片打包到dist/images中 }, 2)url-loader 像file-loader一样工作,但如果文件小于限制,可以返回data URL 好处是直接将小图打包以base64打包在js中,减少Http请求次数,提高效率 安装url-loader 执行命令:npm install -D url-loader 注意url-loader依赖file-loader,因此安装url-loader需要先安装file-loader 安装完成之后在package.json中增加 "devDependencies": { "url-loader": "^4.1.1" } 然后在webpack.config.js中配置 把之前的file-loader 改成url-loader module.exports = { module:{ rules:[{ test:/\.(jpg|jpeg|png|svg)$/, // 以这些文件结尾的文件进行file-loader打包 loader:'url-loader', options:{ name:'[name].[ext]', outputPath:"images" // 将图片打包到dist/images中 } }] } } 2、CSS文件打包 webpack通过css-loader和style-loader来打包css文件。 css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。 css-loader:解决文件之间的依赖关系,把所有的css文件打包成一个文件 style-loader将css-loader打包完成后生成的文件挂载到页面head标签的中 1)安装 npm install --save-dev css-loader npm install --save-dev style-loader 2)然后把 loader 引用到你 webpack 的配置中。如下所示 module.exports = { module: { rules: [ { test: /\.css$/i, use: ["style-loader", "css-loader"], // use使用两个loader }, ], }, }; 注意: use使用两个loader,顺序是有讲究的, 按照从右到左,从下到上依次执行 3)测试 在App.vue中测试 import './assets/styles/reset.css' 3.打包stylus文件 1)推荐的vscode插件与配置 stylus做为node项目中普遍使用的预处理器别广泛应用于vue项目中。 大家会发现大部分的vue项目中都会使用stylus编写css。 language-stylus:提高语法高亮效果和一些支持 Supremacy:自动格式化stylus插件,可以根据个人习惯或公司要求, 指定stylus格式。 2)打包stylus文件 1.安装stylus-loader 执行命令 npm install -D stylus stylus-loader stylus:是stylus文件预处理程序,作用是将stylus编译成css格式 stylus-loader:加载stylus文件,调用stylus预处理程序形成css文件。 安装完成之后在package.json中确认成功安装 "devDependencies": { "style-loader": "^2.0.0", "stylus": "^0.54.8", } 2.在webpack.config.js中配置 module.exports = { module: { rules: [ { test: /\.styl(us)?$/, // 正则匹配以styl结尾或者stylus结尾的文件 use:['style-loader','css-loader','stylus-loader'] }, ], }, } 3.测试 在src/assets路径新建global.stylus,写入: .border-f0f border:1px solid #00B7FF border-radius:5px 在App.vue中测试 import './assets/styles/global.styl' 3)处理vue文件中的stylus 在vue-loader的官方文档中找到关于stylus的配置 1.安装 在前面已经安装了stylus和stylus-loader,这里就不用在安装了。 2.配置webpack.config.js 把上一步的'style-loader' 改成 'vue-style-loader' module.exports = { module: { rules: [ { test: /\.styl(us)?$/, // 正则匹配以styl结尾或者stylus结尾的文件 use:['vue-style-loader','css-loader','stylus-loader'] // }, ], }, } 注意哦:在这一步并没有安装vue-style-loader,但竟然可以直接使用。 打开node_modules找到vue-loader依赖包,在找到它的package.json 发现已经包含了 "vue-style-loader",所以在这一步不需要再安装 "vue-style-loader" 【六、插件】 在某个时间点上,自动执行的处理程序。 1.使用html-webpack-plugin插件 html-webpack-plugin 插件是用于编译 Webpack 项目中的 html 类型的文件, 如果直接将 html 文件置于 ./src 目录中, 用 Webpack 打包时是不会编译到生产环境中的,即在打包生成的dist目录下没有 index.html文件。 通过html-webpack-plugin打包的时候在dist目录生成一个html文件 1)安装 npm install --save-dev html-webpack-plugin 安装完成到package.json确认 "devDependencies": { "html-webpack-plugin": "^5.3.1" } 2)配置 在webpack.config.js配置 //引入html-webpack-plugin const htmlWebpackPlugin = require('html-webpack-plugin') module.exports = { // 插件 plugins:[ new htmlWebpackPlugin({ template:'./index.html' // 指定根目录的index.html作为模板,生成到dist目录下 }) ], } 3)打包测试 删除原来的dist文件,执行打包命令再次生成dist文件, 发现dist生成index.html文件,在浏览器打开报错,原因是 生成的index.html文件不包含
,解决 方案是指定根目录的index.html作为模板,生成到dist目录下 4)指定模板 指定根目录的index.html作为模板,生成到dist目录下 // 插件 plugins:[ new htmlWebpackPlugin({ template:'./index.html' // 指定根目录的index.html作为模板,生成到dist目录下 }) ], 5)小结 html-webpack-plugin的作用: 在打包结束时,在dist目录下自动生成index.html文件,并把打包好的js文件引入打html中 2.使用clean-webpack-plugin 生产环境编译文件的时候,先把 build或dist (就是放生产环境用的文件) 目录里的文件先清除干净,再生成新的。 1)安装 npm install --save-dev clean-webpack-plugin 安装完成到package.json确认 "devDependencies": { "clean-webpack-plugin": "^4.0.0-alpha.0", } 2)配置 //引入clean-webpack-plugin const { CleanWebpackPlugin } = require('clean-webpack-plugin') module.exports = { // 插件 plugins:[ new CleanWebpackPlugin() ], } 3)打包测试 3.使用autoprefixer插件 autoprefixer插件是postcss-loader提供的一个插件如果使用这个插件, 需要先那幢postcss-loader。 autoprefixer可以自动在样式中添加浏览器厂商前缀,避免手动处理样式兼容问题 1)安装 npm install --save-dev postcss postcss-loader autoprefixer package.json中添加了: "devDependencies": { "autoprefixer": "^10.2.5", } 2)webpack.config.js中配置autoprefixer // 添加postcss-loader和插件配置 module.exports = { //打包规则 module:{ { test: /\.styl(us)?$/, // 正则匹配以styl结尾或者stylus结尾的文件 use:[ // 执行顺序是从下向上 'vue-style-loader', 'css-loader', { loader: "postcss-loader", options:{ postcssOptions:{ plugins: [ require('autoprefixer') ] } } }, 'stylus-loader' ] }] } } } 3)打包测试 测试样式代码 .trans transform:translate(100px,10px) 打包之后测试发现不生效,解决方法: 在package.json文件添加: "browserslist": [ "last 2 version", "> 1%", "iOS >= 7", "Android > 4.1", "Firefox > 20" ] 注意这个"browserslist"在webpack5有bug,devServer启动不会实时刷新页面。 【七.开发环境设置】 1.devServer webpack-dev-server 提供了一个简单的web服务器,webpack会自动重新打包,页面会重新刷新加载,这样就不需要每次执行打包命令。 1)配置devServer 安装命令 npm install --save-dev webpack-dev-server 2)基本配置 修改webpack.config.js配置文件,高数开发服务器(dev server)在哪里找文件 module.exports = { mode:'development', devServer:{ // 指定服务器根目录 contentBase:'./dist', //自动打开浏览器 open:true }, } 在package.json中添加一个脚本 "script":{ "dev": "webpack serve --env development" } 在命令行中执行npm run dev 启动devServer 注意在package.json中配置"browserslist"之后, 在webpack5有bug,devServer启动可以自动编译但不会实时刷新页面, 解决方法是在webpack配置中指定 target: "web" module.exports = { target: "web" } 3)常用配置 hoost:服务器主机 port:端口 hort:热模块替换 proxy:代理 指定(ajax)请求转发 2.热模块替换(Hot Module Replacement或者HMR) 它允许在运行时候更新各种各样的模块, 而无需进行完全刷新。 比如,不在刷新的时候更新css样式 热模块替换不适合用于生产环境,这意味着只适合在开发环境中使用。 注意开启热模块之后,页面不会实时刷新 1)配置。 module.exports = { devServer:{ // 指定服务器根目录 contentBase:'./dist', //自动打开浏览器 open:true, // 端口 port:8080, // 热模块替换,开启热模块之后,页面不会实时刷新,但能不刷新页面更新css样式 hot:true } } 2)插件 // 导入webpack const webpack = require('webpack') module.exports = { plugins:[ new webpack.HotModuleReplacementPlugin(), // 热模块 ] } 3)测试 在App.vue组件测试 第一步.在页面手动添加DOM节点内容 第二步.在App组件代码里面修改该处的css样式 观察发现页面样式更改的时候新增的DOM节点并没消息 3.SourceMap(源代码映射) 建立打包后的文件和源代码所在行的映射,主要作用 在开发是快速定位到出错的代码行。 module.exports = { devtool: 'inline-source-map', } 【八、生产环境】 webpack.dev.js:用于开发环境 webpack.prod.js:用于生产环境 1.分别制定两个配置文件和package.json脚本 webpack.dev.js: /** * 开发环境所需要的配置 * */ // 导入path模块 const path = require('path') //引入vue-loader插件,解决遇到是vue结尾的文件,使用vue-loader来打包 const VueLoaderPlugin = require('vue-loader/lib/plugin') //引入html-webpack-plugin ,指定根目录的index.html作为模板,生成到dist目录下 const HtmlWebpackPlugin = require('html-webpack-plugin') //引入clean-webpack-plugin,这个在打包之前清除打包生成的文件 (dist) const { CleanWebpackPlugin } = require('clean-webpack-plugin') // 导入webpack,热模块需要使用到 const webpack = require('webpack') module.exports = { // 打包模式,development mode: 'development', //打包的入口文件 entry: './src/main.js', devServer: { // 指定服务器根目录 contentBase: './dist', host: 'localhost', //自动打开浏览器 open: true, // 端口 port: 8080, // 热模块替换 hot: true }, // 打包的出口 output: { filename: 'app.js', path: path.resolve(__dirname, 'dist') }, devtool: 'eval', //打包规则 module: { rules: [{ test: /\.vue$/, //遇到是vue结尾的文件,使用vue-loader来打包 loader: 'vue-loader' }, { test: /\.(jpg|jpeg|png|svg)$/, // 以这些文件结尾的文件进行file-loader打包 loader: 'url-loader', options: { name: '[name].[ext]', outputPath: "images", // 将图片打包到dist/images中 limit: 1024 * 20 // 小于这个值(20K)就会以base64打包在js里面(以字节为单位) // 当文件小于limit值的时候以base64打包在js里面,当大于limit的时候使用file-loader打包 } }, { test: /\.css$/, // 遇到是css结尾的文件 use: [ // 注意这里使用两个loader,执行顺序是从右到左,从下到上 'style-loader', 'css-loader' ] }, { test: /\.styl(us)?$/, // 正则匹配以styl结尾或者stylus结尾的文件 use: [ // 执行顺序是从下向上 'vue-style-loader', 'css-loader', { loader: "postcss-loader", options: { postcssOptions: { plugins: [ require('autoprefixer') ] } } }, 'stylus-loader' ] }] }, // 插件 plugins: [ new VueLoaderPlugin(), new HtmlWebpackPlugin({ template: './index.html' // 指定根目录的index.html作为模板,生成到dist目录下 }), new CleanWebpackPlugin(), // 打包之前先清空生成的打包文件(dist) new webpack.HotModuleReplacementPlugin(), // 热模块 ], // 添加别名 resolve: { alias: { 'vue': 'vue/dist/vue.js' } } } webpack.prod.js: /** * 生产环境所需要的配置 * */ // 导入path模块 const path = require('path') //引入vue-loader插件,解决遇到是vue结尾的文件,使用vue-loader来打包 const VueLoaderPlugin = require('vue-loader/lib/plugin') //引入html-webpack-plugin ,指定根目录的index.html作为模板,生成到dist目录下 const HtmlWebpackPlugin = require('html-webpack-plugin') //引入clean-webpack-plugin,这个在打包之前清除打包生成的文件 (dist) const { CleanWebpackPlugin } = require('clean-webpack-plugin') module.exports = { // 打包模式production mode: 'production', //打包的入口文件 entry: './src/main.js', // 打包的出口 output: { filename: 'app.js', path: path.resolve(__dirname, 'dist') }, //打包规则 module: { rules: [{ test: /\.vue$/, //遇到是vue结尾的文件,使用vue-loader来打包 loader: 'vue-loader' }, { test: /\.(jpg|jpeg|png|svg)$/, // 以这些文件结尾的文件进行file-loader打包 loader: 'url-loader', options: { name: '[name].[ext]', outputPath: "images", // 将图片打包到dist/images中 limit: 1024 * 20 // 小于这个值(20K)就会以base64打包在js里面(以字节为单位) // 当文件小于limit值的时候以base64打包在js里面,当大于limit的时候使用file-loader打包 } }, { test: /\.css$/, // 遇到是css结尾的文件 use: [ // 注意这里使用两个loader,执行顺序是从右到左,从下到上 'style-loader', 'css-loader' ] }, { test: /\.styl(us)?$/, // 正则匹配以styl结尾或者stylus结尾的文件 use: [ // 执行顺序是从下向上 'vue-style-loader', 'css-loader', { loader: "postcss-loader", options: { postcssOptions: { plugins: [ require('autoprefixer') ] } } }, 'stylus-loader' ] }] }, // 插件 plugins: [ new VueLoaderPlugin(), new HtmlWebpackPlugin({ template: './index.html' // 指定根目录的index.html作为模板,生成到dist目录下 }), new CleanWebpackPlugin(), // 打包之前先清空生成的打包文件(dist) ], // 添加别名 resolve: { alias: { 'vue': 'vue/dist/vue.js' } } } 配置package.json脚本 "scripts": { "dev": "webpack serve --config ./webpack.dev.js", "build": "webpack --config ./webpack.prod.js" }, 2.提取公共部分 webpack.dev.js和webpack.dev.js有绝大部分代码是相同的, 可以提取共同部分。 使用webpack-merge工具提取共同部分代码。 1)安装 npm install -D webpack-merge 2)创建build目录 创建3个文件 webpack.base.js 公共配置 webpack.dev.js开发环境配置 webpack.prod.js生产环境配置 并且将原来根目录的webpack配置删除 webpack.base.js代码: /** * 公共配置 * */ // 导入path模块 const path = require('path') //引入vue-loader插件,解决遇到是vue结尾的文件,使用vue-loader来打包 const VueLoaderPlugin = require('vue-loader/lib/plugin') //引入html-webpack-plugin ,指定根目录的index.html作为模板,生成到dist目录下 const HtmlWebpackPlugin = require('html-webpack-plugin') //引入clean-webpack-plugin,这个在打包之前清除打包生成的文件 (dist) const { CleanWebpackPlugin } = require('clean-webpack-plugin') module.exports = { //打包的入口文件 entry: './src/main.js', // 打包的出口 output: { filename: 'app.js', path: path.resolve(__dirname, '../dist') }, //打包规则 module: { rules: [{ test: /\.vue$/, //遇到是vue结尾的文件,使用vue-loader来打包 loader: 'vue-loader' }, { test: /\.(jpg|jpeg|png|svg)$/, // 以这些文件结尾的文件进行file-loader打包 loader: 'url-loader', options: { name: '[name].[ext]', outputPath: "images", // 将图片打包到dist/images中 limit: 1024 * 20 // 小于这个值(20K)就会以base64打包在js里面(以字节为单位) // 当文件小于limit值的时候以base64打包在js里面,当大于limit的时候使用file-loader打包 } }, { test: /\.css$/, // 遇到是css结尾的文件 use: [ // 注意这里使用两个loader,执行顺序是从右到左,从下到上 'style-loader', 'css-loader' ] }, { test: /\.styl(us)?$/, // 正则匹配以styl结尾或者stylus结尾的文件 use: [ // 执行顺序是从下向上 'vue-style-loader', 'css-loader', { loader: "postcss-loader", options: { postcssOptions: { plugins: [ require('autoprefixer') ] } } }, 'stylus-loader' ] }] }, // 插件 plugins: [ new VueLoaderPlugin(), new HtmlWebpackPlugin({ template: './index.html' // 指定根目录的index.html作为模板,生成到dist目录下 }), new CleanWebpackPlugin(), // 打包之前先清空生成的打包文件(dist) ], // 添加别名 resolve: { alias: { 'vue': 'vue/dist/vue.js' } } } webpack.dev.js代码 /** * 开发环境配置 * */ // 引入公共配置 const baseConfig = require('./webpack.base.js') // 提取公共代码 const { merge } = require('webpack-merge') // 导入webpack,热模块需要使用到 const webpack = require('webpack') const devConfig= { // 打包模式,development mode: 'development', devServer: { // 指定服务器根目录 contentBase: './dist', host: 'localhost', //自动打开浏览器 open: true, // 端口 port: 8080, // 热模块替换 hot: true }, devtool: 'eval', // 插件 plugins: [ new webpack.HotModuleReplacementPlugin(), // 热模块 ] } // 将公共配置和开发环境的配置合并导出 module.exports = merge(baseConfig,devConfig) webpack.prod.js代码: /** * 生产环境配置 * */ // 引入公共配置 const baseConfig = require('./webpack.base.js') // 提取公共代码 const { merge } = require('webpack-merge') const prodConfig = { // 打包模式production mode: 'production' } // 将公共配置和开发环境的配置合并导出 module.exports = merge(baseConfig,prodConfig) 3)改写package配置 "scripts": { "dev": "webpack serve --config ./build/webpack.dev.js", "build": "webpack --config ./build/webpack.prod.js" } 【九、解析ES6语法】 在项目中,有时候可能会使用到ES6的语法,二这些内容在低版本浏览器是不支持的。 在低版本浏览器往往不能正常解析ES6语法,一般我们会使用babel将ES6编译成ES5的语法。 1)安装 npm install --save-dev babel-loader @babel/core 2)配置 module.exports = { module: { rules: [ { test: /\.m?js$/, exclude: /node_modules/, use: { loader: "babel-loader", options: { presets: ['@babel/preset-env'] } } } ] } } 3)在根目录创建 .babelrc文件,写入代码: { "presets": ["@babel/preset-env"] } 安装一个编译工具 npm install @babel/preset-env --save-dev