- 👯 I’m looking to collaborate on front-end development
- 📫 How to reach me: [email protected]
mario34 / blog Goto Github PK
View Code? Open in Web Editor NEW🏀 Mario34的博客
🏀 Mario34的博客
记录日常的踩坑,在找到解决方案后做个记录
背景:在一个老的项目中,使用的是 eslint + @typescript-eslint/parser
问题描述:eslint有时会出现异常的校验,尽管代码符合规范,并且自动修复会使代码完全混成一坨。最后定位到是@typescript-eslint/parser 的问题,升级本本就解决了issues
特此记录
最初的问题是在调用createVideoContext
createAudioContext
createMapContext
等方法时,第二个参数时当前组件的实例。
函数式组件如何访问组件实例issues、useScope官方文档
const $scope = useScope()
$scope 指向该组件对应的小程序组件实例
.native
修饰符后组件的所有事件将会绑定到组件内部的跟元素// 组件
<button>
<slot/>
</button>
<components @click="onClick" />
表现出来的是即使组件内部没有emit
暴露任何事件,组件外部也可以直接声明根元素上的原生事件(click
,keyup
...)
相关PR
首先初始化项目
npm init
要安装最新版本或特定版本,请运行以下命令之一:
npm install --save-dev webpack
npm install --save-dev webpack@<version>
如果你使用 webpack 4+ 版本,你还需要安装 CLI。
npm install --save-dev webpack-cli
mkdir ./src ./public ./src/components
vim ./src/index.js
vim ./src/components/HelloWord.js
vim ./public/index.html
# 文件目录格式
|-- Webpack
|-- package-lock.json
|-- package.json
|-- webpack.config.js
|-- public
|-- src
|-- index.js
<!-- public/index.js-->
<body>
<div id="app"></div>
</body>
// src/index.js
import React from "react";
import HelloWorld from "./components/HellowWorld";
class App extends React.Component {
render() {
return <HelloWorld />;
}
}
ReactDOM.render(<App />, document.getElementById("app"));
// src/components/HelloWorld.js
import React from "react";
export default class App extends React.Component {
render() {
return <h1>Hello World</h1>;
}
}
根据上述文件目录结构,新建配置文件 public/webpack.common.js
const path = require("path");
const webpack = require("webpack");
function resolve(dir) {
return path.join(__dirname, "..", dir);
}
module.exports = {
entry: "./src/index.js",
output: {
path: util.resolve("dist"),
filename: "[name].js",
chunkFilename: "[chunkhash].js",
jsonpFunction: "myWebpackJsonp"
}
};
在packge.json
添加
"scripts": {
"dev": "webpack --config ./build/webpack.common.js"
},
尝试运行npm run dev
ERROR in ./src/index.js 7:11
Module parse failed: Unexpected token (7:11)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| class App extends React.Component {
| render() {
> return <HelloWorld />;
| }
| }
webpack
告诉我们需要使用加载器来处理该文件,针对 react 文件,需要使用babel-loader
,对于其他的格式文件,需要进行配置。
由于配置中会用到一些工具,所以新建/build/util.js
,引入util.js
const path = require("path");
//返回项目根目录下的dir路径
exports.resolve = function(dir) {
return path.join(__dirname, "..", dir);
};
//返回dits中文件路径下的dir路径
exports.staticPath = function(dir) {
return path.join("static/", dir);
};
npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react
在webpack.config.js
添加 babel 配置
...
module: {
rules: [
{
test: /\.js?$/,
include: [util.resolve('src')],
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react']
}
}
}
]
}
...
sass-loader
依赖node-sass
,由于这个包存放在 github 上,下载速度比较慢,可使用淘宝源下载
npm install sass-loader node-sass css-loader style-loader --save-dev --registry https://registry.npm.taobao.org
在webpack.config.js
rules 添加配置
...
{
test: /\.css$/,
use: [{ loader: "style-loader" }, { loader: "css-loader" }]
},
{
test: /\.scss$/,
use: [
{ loader: "style-loader" }, // 将 JS 字符串生成为 <style> 节点
{ loader: "css-loader" }, // �将 CSS 转化成 CommonJS 模块
{ loader: "sass-loader" } // 将 Sass 编译成 CSS
]
}
...
关于图片或文件的相关loader
:
file-loader
默认情况下,生成的文件的文件名就是文件内容的 MD5 哈希值并会保留所引用资源的原始扩展名。
url-loader
功能类似于 file-loader,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL。url-loader
依赖 file-loader
这里选择使用url-loader
npm install --save-dev url-loader file-loader
在webpack.config.js
rules 添加配置
...
{
test: /\.(png|jpg|jpeg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 6000,
name: util.staticPath('images/[name][hash].[ext]'),
}
}
]
}
...
区分production
和 development
环境下的配置
vim ./build/webpack.dev.js ./build/webpack.prod.js
# 用于合并webpack配置
npm install --save-dev webpack-merge
# 分别用于构建时清除dist目录和拷贝处理index.html
npm install --save-dev clean-webpack-plugin html-webpack-plugin
# 用于启动开发服务器
npm install --save-dev webpack-dev-server
# 用于开发时模块热重载
npm install --save-dev hot-module-replacement-plugin
# 产品模式压缩js
npm install --save-dev uglifyjs-webpack-plugin
# 提取css、压缩css(替代ExtractTextWebpackPlugin)
npm install --save-dev mini-css-extract-plugin
# 注入process.env变量
npm install --save-dev cross-env
loader
配置中MiniCssExtractPlugin.loader
与style-loader
不能同时使用。
修改webpack.common.js
const devMode = process.env.NODE_ENV !== 'production'
...
//rules
{
test: /\.css$/,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
"css-loader"
]
},
{
test: /\.scss$/,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
{ loader: "css-loader" }, // �将 CSS 转化成 CommonJS 模块
{ loader: "sass-loader" } // 将 Sass 编译成 CSS
]
},
...
...
plugins: [
new HtmlWebpackPlugin({
template: util.resolve('public/index.html'),
filename: util.resolve('dist/index.html'),
favicon: util.resolve('public/favicon.ico')
}),
],
resolve: {
extensions: [".js", ".json", ".jsx", ".css"],
alias: {
'@': util.resolve('src')//路径别名 可添加 jsconfig.json 配合编辑器提供路径提示功能
}
},
...
分别添加webpack.prod.js
webpack.dev.js
文件
webpack.prod.js
const merge = require("webpack-merge");
const UglifyJSPlugin = require("uglifyjs-webpack-plugin");
const common = require("./webpack.common.js");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = merge(common, {
mode: "production",
output: {
path: util.resolve("dist"),
filename: util.staticPath("js/[name].[chunkhash].js"),
chunkFilename: util.staticPath("js/[id].[chunkhash].js")
},
plugins: [
new webpack.DefinePlugin({
'env.PRODUCTION': "true",
}),
new UglifyJSPlugin(),
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: util.staticPath("style/[name].css"),
chunkFilename: util.staticPath("style/[id].css")
})
]
});
webpack.dev.js
const merge = require("webpack-merge");
const common = require("./webpack.common.js");
const webpack = require("webpack);
module.exports = merge(common, {
mode: "development",
devServer: {
contentBase: "./dist"
},
pluging: [new webpack.HotModuleReplacementPlugin()],
devtool: "source-map"
});
"dev": "cross-env NODE_ENV=development webpack-dev-server --inline --progress --config ./build/webpack.dev.js"
"build": "cross-env NODE_ENV=production webpack --config ./build/webpack.prod.js"
现在执行npm run dev
将会得到一个简单的开发环境
到此为止我们完成了一个简单的配置,在开发环境下实现热重载、加载样式文件,生产环境下代码压缩、自动拷贝index.html
并注入script
、打包自动清理dist
文件夹。下面继续完善相关的功能。
配置如下,命令行只显示警告或错误信息,同时使用friendly-errors-webpack-plugin
插件,自动清除信息,并自定义显示信息内容。
npm install --save-dev friendly-errors-webpack-plugin
webpack.dev.js
const devServerConfig = {
contentBase: util.resolve("dist"),
clientLogLevel: "warning",
port: 3000,
hot: true,
host: "localhost",
open: false,
quiet: true,
overlay: {
/**
* Shows a full-screen overlay in the browser
* when there are compiler errors or warnings.
*/
warnings: false,
errors: true
},
proxy: {
// detail: https://www.webpackjs.com/configuration/dev-server/#devserver-proxy
"/base": {
target: "https://test.cn",
secure: true,
changeOrigin: true,
pathRewrite: {
"^/base": ""
}
}
}
};
module.exports = merge(common, {
mode: "development",
plugins: [
new webpack.DefinePlugin({
"env.PRODUCTION": "false"
}),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.HotModuleReplacementPlugin(),
new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [
`You application is running here http://${devServerConfig.host}:${devServerConfig.port}`
]
},
clearConsole: true
})
],
devServer: devServerConfig,
devtool: "source-map"
});
安装依赖
npm install --save-dev chalk ora
新建build/build.js
,修改scripts.build
cross-env NODE_ENV=production node ./build/build.js
,ora
能在命令行显示的加载动画,chalk
能够输出带有颜色的文字或消息。
const webpack = require("webpack");
const webpackConfig = require("./webpack.prod");
const ora = require("ora");
const chalk = require("chalk");
const spinner = ora("buildind...");
spinner.start();
webpack(webpackConfig, (err, stats) => {
spinner.stop();
if (err) throw err;
process.stdout.write(
stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + "\n\n"
);
if (stats.hasErrors()) {
console.log(chalk.red(" Build failed with errors.\n"));
process.exit(1);
}
console.log(chalk.cyan(" Build complete.\n"));
});
首先需要获取本机地址,nodejs
os
模块提供了相关的功能。
build/util.js
...
const os = require('os')
...
exports.localAddress = function(dir) {
var network = os.networkInterfaces()
for (var key in network) {
for (var i = 0; i < network[key].length; i++) {
var item = network[key][i]
if(item.family === 'IPv4'&& item.address !== '127.0.0.1' && !item.internal){
return item.address
}
}
}
}
修改devServerConfig.host
为'0.0.0.0'
,再修改FriendlyErrorsPlugin
配置
/build/webpack.dev.js
...
new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`App running at:\n\n - Local: http://localhost:${devServerConfig.port}/\n - Network: http:/{util.localAddress()}:${devServerConfig.port}`],
},
clearConsole: true
})
...
具有完备的eslint
配置可以极大程度上规范编码格式,同时配合编辑器的保存自动根据配置修复,开发体验较好,如果不想使用eslint
可以在webpack.dev.js
中设置(不推荐)
安装相关插件
npm install --save-dev eslint eslint-friendly-formatter eslint-loader eslint-plugin-react
eslint-loader
配合eslint-friendly-formatter
能够在编译时将代码与eslintrc
冲突的错误显示在命令行
修改webpack.common.js
...
const createLintingRule = () => ({
test: /\.(js|ts|jsx)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [util.resolve('src')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: true
}
})
...
// 可以通过提取一个config配置文来单独开关相关功能而不需要直接修改配置文件
rules:[
...(config.eslint ? [createLintingRule()] : []),
...
]
...
在进行项目开发时统一代码规范十分的重要,这里记录的是我的一些相关操作的经验
随着tslint社区和eslint社区的推动,目前推荐使用eslint做ts的风格校验(安装对应的插件即可@typescript-eslint/eslint-plugin),所以不管是js项目还是ts项目,都使用eslint就对了。
The TypeScript Team themselves also announced their plans to move the TypeScript codebase from TSLint to typescript-eslint, and they have been big supporters of this project. More details at microsoft/TypeScript#30553
Migrating from TSLint to ESLint If you are looking for help in migrating from TSLint to ESLint, you can check out this project: https://github.com/typescript-eslint/tslint-to-eslint-config
不同文件类型的校验使用不同的插件
建议在eslint配置中加入extends: ["eslint:recommended"]
eslint:recommended规则能够校验出常见的代码风格错误,其他的代码风格规则需要在配置中声明
No rules are enabled by default. The "extends": "eslint:recommended" property in a configuration file enables rules that report common problems, which have a check mark below.
eslint-plugin-react
eslint-plugin-vue
确保上述配置正确,如果你使用的是VsCode编辑器,安装eslint插件,并设置编辑器保存时进行fix操作,能够极大的提升工作效率。在代码编写阶段就能够解决代码风格问题,不必等到commit时在去处理风格不一致问题。
WebStorm
用户同样可以实现上述功能,我不太熟悉WebStorm的配置 : )...
目前vue.3.x还处于beta状态,官方的英文文档v3.vuejs.org
尽管模版的写法一直是官方推荐的,除了没法支持类型提示,也没有可挑剔的了。这里选择TypeScript,所以采用tsx的模式代替template
为了实现tsx的加载,需要借助相关的loader插件 @ant-design-vue/babel-plugin-jsx、HcySunYang/vue-next-jsx
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.