Babel won't transpile Vue dependencies - javascript

I have a Vue.js Single File Component which depends on primevue/AutoComplete.vue.
When transpiling the code for IE11 (I know, I know) the files produced from AutoComplete.vue are ignored and therefor not transpiled resulting in errors in Internet Explorer.
I have adjusted my babel-loader config as described here and the relevant part of my webpack config now looks like this:
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
exclude: file => (/node_modules/.test(file) && !/\.vue\.js/.test(file))
},
presets: [
["#babel/preset-env",
{
"useBuiltIns": "usage",
"debug": true,
"modules": false,
"corejs": { version: "3.6", proposals: true }
}
]
]
}
}
]
},
Looking at the suggested exclude function, it relies on files having the suffix e.g. AutoComplete.vue.js but when I log the "file" parameter, I don't see any file with this suffix.
How is it supposed to filter the nested Vue dependencies if the proposed file ending isn't provided by vue-loader ? Am I missing these dependencies because of a config error ?

Related

Webpack. Different rules for different entry points with similar test-mask

We have a project with old-good-smarty-part and react-part.
We bundle react-part files with webpack.
We want to bundle non-react-part files with webpack too, but this files are a bit upper than webpack in project-tree. And here is a problem: we need to bundle them and place result to grand-grand-parent directory... So, how to split rules for this entry-point?
const ExtractJS = new ExtractTextPlugin({
filename: "../../[name].min.js"
});
module.exports = {
entry: {
reactApp: ["./src/entries/reactApp/index.tsx"],
// JS -- we need to place it "upper" than webpack directory in project
"scripts/oldStuff": ["./src/entries/oldStuff/index.js"]
},
module: {
rules: [
{
test: /\.js?$/,
loader: "babel-loader",
exclude: /node_modules/,
options: {
cacheDirectory: true,
presets: [["es2015", { modules: false }], "stage-2", "react"],
plugins: ["transform-node-env-inline"],
env: {
development: {
plugins: ["react-hot-loader/babel"]
},
targets: {
browsers: ["last 2 versions", "ie >= 10"]
}
}
}
},
{
test: /\.js?$/,
include: [/(.*?)scripts(.*?)/, /(.*?)lib(.*?)/],
use: ExtractJS.extract({
use: {
loader: "raw-loader"
}
})
}
}
}
}
was tryed to solve this with include and exclude options, but this looks not good -- we got "cross-entry" files (something like /lib/foo/bar.js for react part and /lib/foo/boar.js for non-react part) and its about 15-20 files...
And here is a main question: is it possible to exclude entry-point for one rule and include it for another one (with exception of other entry-points)?

Import TypeScript Module to JavaScript

I have a module in TypeScript that look as follows:
import { CallerId, CallScreening, CustomTagRef, MediaRef, OutboundSettings, ServiceCommon }
from '../src/shared/domain/dto';
import { ServiceCommonEntity } from '../src/shared/domain/entity';
import { CallerIdMode, ResourceRefType } from '../src/shared/domain/enum';
export const CONTACT_PAYLOAD = 'payload';
export const ACCOUNT_PAYLOAD = 'a_payload';
export function getFakeAccountPayload() {
return fake_payload;
}
In the same project I have a js file in which I want to use functions from my .ts file.
How can I import my ts module to my js file?
Sometimes we face such situation in our projects. I am pretty sure that you are migrating some part of your code to typescript and somewhere in your project you need typescript in javascript file and creating javascript file for same ts file is not way to solve the problem, but If you really want to use typescript(.ts) in javascript(.js) files, so here is the one possible solution, I am assuming that your are suing webpack bundler, so you use ts-loader and babel-loader in your webpack. here are rule for your webpack configuration(Note: you must have airbnb preset, ts-loader, and all plugins installed)
{
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.jsx?/,
use: {
loader: 'babel-loader',
options: {
presets: ['airbnb'],
plugins: ['#babel/plugin-transform-modules-commonjs', '#babel/transform-async-to-generator', 'source-map-support', 'babel-plugin-root-import'],
ignore: ['node_modules/is_js'],
},
},
exclude: /node_modules\/(?query-string|strict-uri-encode)/,
}
]
}
In case of running spec, if you are using jest you might also need .babelrc configuration for tests
{
"presets": [
"airbnb",
"#babel/preset-typescript"
],
"env": {
"development": {
"sourceMaps": true,
"plugins": ["source-map-support"]
}
},
"plugins": ["#babel/plugin-transform-modules-commonjs", "#babel/plugin-proposal-class-properties", "#babel/transform-async-to-generator", "babel-plugin-root-import"],
"ignore": ["node_modules/is_js"]
}
We also have one article which might be helpful. Use .ts File .js file

How to exclude core-js using useBuiltIns: "usage"

Using babel 7.5.5, core-js 3.1.4 and webpack 4.38.0, how can I exclude core-js from transpiling?
I do not want to exclude node_modules altogether since I have libs that need transpiling
If I use exclude: /node_modules\/(core-js)/, a core-js module throws
TypeError: $ is not a function
This leaves me with two other options.
Use includes instead, include my src directory and every dependency that needs transpiling one by one
Use useBuiltIns: entry instead of usage, since in this case exclude: /node_modules/\(core-js)/ works, and import core.js at the top of main.js
Both of these options don't really seem like good solutions to me since usage is "no longer experimental" since 7.4.
Is there any way to make it work using usage? Is it a bug in either babel-loader or babel? Or is my configuration at fault?
This is my Webpack config:
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'production',
entry: {
main: ['./src/main'],
},
output: {
path: path.resolve(__dirname, './build/'),
publicPath: '/build/'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules\/(core-js)/,
use: {
loader: 'babel-loader'
},
},
{
test: require.resolve('jquery'),
use: [
{
loader: 'expose-loader',
options: 'jQuery'
},
{
loader: 'expose-loader',
options: '$'
}
]
}
]
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
})
],
};
This is my babel config:
module.exports = function (api) {
api.cache(true);
return {
presets: [
[
'#babel/preset-env',
{
corejs: {
version: 3,
},
useBuiltIns: 'usage',
}
]
],
};
};
You can reproduce the error with the following repository: https://github.com/tomm1996/usebuiltins-exclude-test
You need to exclude both core-js and webpack/buildin from the Babel transpilation.
You can use the folling exclude Regexes:
exclude : [
/\bcore-js\b/,
/\bwebpack\/buildin\b/
]
Here is also a complete babel-loader configuration with some useful comments:
{
module : {
rules : [{
test : /\.js$/,
// Some module should not be transpiled by Babel
// See https://github.com/zloirock/core-js/issues/743#issuecomment-572074215
exclude : [
/\bcore-js\b/,
/\bwebpack\/buildin\b/
],
loader : "babel-loader",
options : {
babelrc : false,
// Fixes "TypeError: __webpack_require__(...) is not a function"
// https://github.com/webpack/webpack/issues/9379#issuecomment-509628205
// https://babeljs.io/docs/en/options#sourcetype
sourceType : "unambiguous",
presets : [
["#babel/preset-env", {
// Webpack supports ES Modules out of the box and therefore doesn’t require
// import/export to be transpiled resulting in smaller builds, and better tree
// shaking. See https://webpack.js.org/guides/tree-shaking/#conclusion
modules : false,
// Adds specific imports for polyfills when they are used in each file.
// Take advantage of the fact that a bundler will load the polyfill only once.
useBuiltIns : "usage",
corejs : {
version : "3",
proposals : true
}
}]
]
}
}
}
}
See https://github.com/zloirock/core-js/issues/743#issuecomment-572074215
Edit: Also if you try to use #babel/plugin-transform-runtime:
plugins : [
// Require the Babel runtime as a separate module to avoid the duplication
// https://webpack.js.org/loaders/babel-loader/#babel-is-injecting-helpers-into-each-file-and-bloating-my-code
["#babel/plugin-transform-runtime", {
// Requires #babel/runtime-corejs3
// https://babeljs.io/blog/2019/03/19/7.4.0#migration-from-core-js-2
corejs : { version: 3, proposals: true }
}],
}
You may run into a similar error:
Uncaught TypeError: _typeof2 is not a function
at _typeof (typeof.js:8)
at eval (sockjs.js:123)
at Object.eval (sockjs.js:131)
at eval (sockjs.js:6565)
at Object../node_modules/sockjs-client/dist/sockjs.js (main.js:13790)
at __webpack_require__ (main.js:70)
at eval (webpack://PUBLIC_ENGINE/(:8000/webpack)-dev-server/client/clients/SockJSClient.js?:110:14)
at Object../node_modules/webpack-dev-server/client/clients/SockJSClient.js (main.js:13874)
at __webpack_require__ (main.js:70)
at eval (webpack://PUBLIC_ENGINE/(:8000/webpack)-dev-server/client/socket.js?:56:41)
This can be solved by excluding #babel/runtime-corejs3 from the transpilation:
exclude : [
/\bcore-js\b/,
/\bwebpack\/buildin\b/,
/#babel\/runtime-corejs3/
]

Defining multiple babel preset configurations in webpack config

I have created a webpack.config.js file that is exporting two different WebPack configuration objects. I need to set up different babel options for presets within these . After a bit of research I have tried creating two different loader configs, each passing a different targets option to the presets like so:
// default JS loader config for browsers that support <script type='module'
{
loader:'babel-loader',
options:{
presets: ['#babel/preset-env', {
targets: {
esmodules: true
}
}]
}
}
...
// fallback for browsers that load the <script nomodule
{
loader:'babel-loader',
options:{
presets: ['#babel/preset-env', {
targets: "> 0.5% in UK, last 2 versions, not dead, ie 11"
}]
}
}
However I am clearly going about this wrong because I get this error on WebPack build
ERROR in ./some-path/WorkflowStage.class.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
ReferenceError: [BABEL] e:\some-path\WorkflowStage.class.js: Unknown option: .targets. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options.
I think the crux of the question is: how should I be passing the target option to #babel/preset-env from within my webpack.config.js file when I have multiple presets?
Basically your loader options must look like a JS-encoded .babelrc. Each preset with options must be in it's own array.
So, replace
{
loader: 'babel-loader',
options: {
presets: [
// defines the #babel/preset-env as the first preset
'#babel/preset-env',
// defines an invalid object as a preset (throws error)
{ targets: { esmodules: true } }
]
}
}
with
{
loader: 'babel-loader',
options: {
presets: [
// defines a preset with options
[
'#babel/preset-env', {
targets: {
esmodules: true
}
}
]
]
}
}

How to use the kind of TypeScript in a Single File Component with Vue?

I'm trying to use the TypeScript benefits in a Vue SFC,
Install the ts-loader, typescript dependencies
I added the tsconfig.json configuration
// tsconfig.json
{
"compilerOptions": {
// this aligns with Vue's browser support
"target": "es5",
// this enables stricter inference for data properties on `this`
"strict": true,
// if using webpack 2+ or rollup, to leverage tree shaking:
"module": "es2015",
"moduleResolution": "node"
}
}
But when trying to compile the next component it shows me error.
<script lang="ts">
import Vue from "vue";
import { mapState,mapGetters } from 'vuex'
export default Vue.extend({
data() {
return {
number : 0
}
},
methods:{
// error void
upCount() : void {
this.$store.commit('increment');
},
downCount() : void{
this.$store.commit('decrement');
},
upCountBy() : void {
this.$store.commit('incrementBy',{count : this.number});
}
},
....
the error
Module parse failed: Unexpected token (45:12) You may need an
appropriate loader to handle this file type.
I am using VueJs together with WebPack from a Laravel and Laravel Mix base installation. How do I solve this?
When I started using Vue and TypeScript, I ran into similiar problems at first and it took me quite a while to get it to work. Try adding this to your webpack.config.js
...
module: {
rules: [
{
test: /\.tsx?$/,
use: [{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [ /\.vue$/ ]
}
}],
exclude: /node_modules/
},
// make sure vue-loader comes after ts-loader
{
test: /\.vue$/,
loader: 'vue-loader'
},
...
Try and flip the order of Connum's suggested answer.
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader',
},
{
test: /\.ts$/,
exclude: /node_modules/,
use: [{ loader: 'ts-loader', options: { appendTsSuffixTo: [/\.vue$/] } }],
},
]
}
Worked for me. You have installed the vue-loader?
npm i -D ts-loader typescript vue-loader

Categories

Resources