Vite import generetad chunks in index.js with url - vuejs3

in my Vue3 project I import the components in the router index.js like that:
{
path: settingsStore.startUri,
name: "home",
component: () => import("../views/Home/Home.vue"),
},
My vite.config looks like that:
import { defineConfig } from "vite";
import vue from "#vitejs/plugin-vue";
import vuetify from "vite-plugin-vuetify";
const path = require("path");
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
// https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/vite-plugin
vuetify({
autoImport: true,
}),
],
define: {
"process.env": {},
__VUE_I18N_FULL_INSTALL__: true,
__VUE_I18N_LEGACY_API__: false,
__INTLIFY_PROD_DEVTOOLS__: false,
},
resolve: {
alias: {
"#": path.resolve(__dirname, "src"),
},
},
build: {
rollupOptions: {
output: {
entryFileNames: "news-[name].js",
assetFileNames: "news-[name].[ext]",
manualChunks: undefined,
chunkFileNames: "chunks/[name].js",
},
},
},
optimizeDeps: {
include: ["vue", "axios"],
},
});
When I run npm run build it creates a chunk directory with some smaller .js files beeing imported in the index.js but as relativ paths like that:
import("./chunks/Home.js")
But I need to import the files from an url like that:
import("https://example.com/chunks/Home.js")
Does anyone know if thats possible and how can I do that?
I tried a lot, read a lot of documentations but didnt find an answer

Related

Cannot read properties of undefined (reading 'scoped')

I'm building an UI Library based on rollup.
An error occurred and I have no idea how to solve it.
TypeError: Cannot read properties of undefined (reading 'scoped')
at transformStyle (C:\my-kit\node_modules\#vitejs\plugin-vue\dist\index.js:4597:19)
at Object.transform (C:\my-kit\node_modules\#vitejs\plugin-vue\dist\index.js:4747:18)
at C:\my-kit\node_modules\rollup\dist\shared\rollup.js:22870:37 {
code: 'PLUGIN_ERROR',
plugin: 'commonjs--resolver',
hook: 'resolveId',
id: 'C:\\my-kit\\packages\\my-ui\\icon\\select-icon-svg.vue?vue&type=style&index=0&scoped=true&lang.less',
it looks like something wrong with parsing vue.
const block = descriptor.styles[index];
the value of block is undefined, error occurred when accessing the scoped property of block.
this is my rollup config. Hope there's someone who can help me.
import { rollup } from "rollup";
import { nodeResolve } from "#rollup/plugin-node-resolve";
import fastGlob from "fast-glob";
import vue from "#vitejs/plugin-vue";
import vueJsx from "#vitejs/plugin-vue-jsx";
import css from "rollup-plugin-css-only";
import commonjs from "#rollup/plugin-commonjs";
import esbuild from "rollup-plugin-esbuild";
import postcss from "rollup-plugin-postcss";
import postcssImport from "postcss-import";
import { babel, getBabelOutputPlugin } from "#rollup/plugin-babel";
import defineOptions from "unplugin-vue-define-options/rollup";
import { UI_PATH } from "./path";
import { resolve } from "path";
import pkgJson from "../packages/my-ui/package.json";
export const buildEsm = async () => {
const input = await fastGlob("**/*.{js,ts,jsx,tsx,vue}", {
cwd: UI_PATH,
absolute: true,
onlyFiles: true,
ignore: ["node_modules"],
});
try {
const bundle = await rollup({
input,
plugins: [
css(),
postcss({
extensions: [".css", ".less", ".scss"],
modules: true,
extract: true,
use: {
sass: null,
stylus: null,
less: { javascriptEnabled: true },
},
plugins: [postcssImport()],
}),
defineOptions(),
vue({
isProduction: false,
}),
vueJsx(),
nodeResolve({
extensions: [".js", ".json", ".ts", ".jsx", ".tsx", ".vue"],
}),
commonjs(),
esbuild({
sourceMap: true,
target: "es2018",
loaders: {
".vue": "ts",
},
}),
getBabelOutputPlugin({
configFile: resolve(__dirname, "../babel.config.js"),
}),
babel({
exclude: "node_modules/**",
extensions: [".js", ".jsx", ".ts", ".tsx", ".vue"],
babelHelpers: "bundled",
}),
],
external: Object.keys(pkgJson.peerDependencies),
});
// write the bundle to disk
await bundle.write({
format: "esm",
dir: resolve(UI_PATH, "es"),
});
} catch (err) {
console.error(err);
}
};

How can I drop console in a VITE2 project?

I tried to drop console for my Vite2 project. I googled and found the terserOptions, however, it didn't work. So I just create a blank template from the offical site with the following code.
yarn create vite my-vue-app --template vue
And then add some console.log on Helloworld page.
the vite.config.js is below:
import { defineConfig } from "vite";
import vue from "#vitejs/plugin-vue";
export default defineConfig({
base: "./",
plugins: [vue()],
bulid: {
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
},
});
After I build the project, the console.log still there. So what's the right way to drop_console on a project built by vite2?
You need to specify in build.minify to use terser.
If not set, terserOptions is ignored as it defaults to using esbuild.
import { defineConfig } from "vite";
import vue from "#vitejs/plugin-vue";
export default defineConfig({
base: "./",
plugins: [vue()],
bulid: {
minify: 'terser', // <-- add
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
},
});
This setting removes console.* at build time.
If you want to use esbuild, you can use this:
esbuild: {
drop: ['console', 'debugger'],
}

webpack not bundling scss when using import instead of require

Simple webpack setup, when I use import to load my scss it is completely missing from the bundle. The line where the import should be is simply missing. When I use require instead, it works.
optimization: {usedExports: true} is not the problem, I tried with and without
mini-css-extract-plugin also did not work.
when I put a typo in the scss it complains, so it is parsed but simply not bundled in the end?
index.js
require("./scss/style.scss");
//import "./scss/style.scss" <--- not working
import { createApp } from 'vue';
import App from './components/App.vue';
const el = document.getElementById('app');
createApp(App).mount(el);
webpack config
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader');
const { DefinePlugin } = require('webpack');
const dist = path.resolve(__dirname, "dist");
module.exports = env => {
const mode = env.production == true ? "production" : "development";
const devtool = mode == "production" ? false : "inline-source-map";
return {
mode: mode,
entry: './web/index.js',
output: {
filename: 'bundle.js',
path: dist
},
optimization: {
usedExports: true,
},
devServer: {
static: {
directory: dist
},
port: 8888
},
module: {
rules: [{
test: /\.(sa|sc|c)ss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
],
}, {
test: /\.(ttf|eot|woff|woff2|svg)$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
},
},
}, {
test: /\.vue$/,
loader: 'vue-loader'
}]
},
plugins: [
new CleanWebpackPlugin(),
new DefinePlugin({
__VUE_OPTIONS_API__: false,
__VUE_PROD_DEVTOOLS__: false,
}),
new HtmlWebpackPlugin({
template: path.resolve("./web/index.html")
}),
new VueLoaderPlugin()
],
resolve: {
extensions: ['.js'],
alias: {
"#": path.resolve(__dirname, 'web')
}
},
devtool
};
};
I found the problem but I don't understand why webpack drops it.
Quote from https://webpack.js.org/guides/tree-shaking/
Note that any imported file is subject to tree shaking. This means if you use something like css-loader in your project and import a CSS file, it needs to be added to the side effect list so it will not be unintentionally dropped in production mode:
In my package.json I put
"sideEffects": false,
to be able to use treeshaking.
But I had to disable it in the loader rule
{
test: /\.(sa|sc|c)ss$/,
use: ['style-loader','css-loader','sass-loader'],
sideEffects: true <----
}

is it possible to use rollup for processing just css?

I know that Rollup is used to bundle .js files. But is it possible to use it just to process css? (css, scss, less, etc).
What i mean is if i had for example in my src folder (the entry folder) a file called index.css and i want rollup to precess it at dist folder (the output folder) like index.css (but processed, for example if there is an imported .sass file or css variables).
How can i do this?
Example rollup.config.js
import { uglify } from 'rollup-plugin-uglify'
import babel from 'rollup-plugin-babel'
import resolve from 'rollup-plugin-node-resolve';
import postcss from 'rollup-plugin-postcss'
const config = [
{
input: 'src/styles/index.scss',
output: {
file: 'dist/style.css',
name: "style",
},
plugins: [
postcss({
plugins: []
})
]
},
];
export default config
src/index.scss:
#import 'other';
h1 {
color: green;
}
src/other.scss
h2 {
color: red;
}
and in the dist folder should be an index.css with the all the code for both css files (and processed).
Something like this:
dist/index.css
h1 {
color: green;
}
h2 {
color: red;
}
You need something like this
import postcss from 'rollup-plugin-postcss'
const config = [
{
input: 'src/styles/index.scss',
output: {
file: 'dist/style.css',
format: 'es'
},
plugins: [
postcss({
modules: true,
extract: true
})
]
},
];
export default config
Just to add to the answer of #Iván and if anyone else gets the error message The emitted file "Filename.css" overwrites a previously emitted file of the same name.:
The postCSS plugin has the option extract: true (like also shown in Iváns answer). When set to true it will create a separate CSS file. So what you can basically do is the following:
Create JS file
Import your styles in the JS file (e.g.: import "../css/index.css" ##Adapt path to your needs)
Now add postCSS to your plugin config:
...
plugins: [
postcss({
modules: true,
extract: true
}),
resolve({
jsnext: true,
browser: true,
}),
commonjs(),
production && terser(),
],
...
This will output a separate CSS file.
Now add the CSS file to your template
Extra: A full config could look like this:
import resolve from "#rollup/plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
import { terser } from "rollup-plugin-terser";
import postcss from "rollup-plugin-postcss";
const production = !process.env.ROLLUP_WATCH;
export default [
{
input: "project/static/src/inputs/index.js",
output: [
{
format: "esm",
name: "map",
file: "project/static/src/outputs/index.min.js",
},
],
plugins: [
postcss({
modules: true,
extract: true
}),
resolve({
jsnext: true,
browser: true,
}),
commonjs(),
production && terser(),
],
},
];

Material 2 attributes in Angular 4 aren't working with webpack, ASP.NET

I'm trying to get Material 2 to work with Angular 4.4.6 using webpack in an ASP.NET Core 2 web application. I get no errors but I currently get no styling and the mat-button attribute has no effect on the output DOM.
I have done the following:
Environment is as follows:
Visual Studio (Professional) 2017 version 15.4.0
ASP.NET Core 2 web application with Angular, from VS template
Update #angular packages to ^4.4.6 in NPM and restore packages
"#angular/animations": "^4.4.6",
"#angular/common": "^4.4.6",
"#angular/compiler": "^4.4.6",
"#angular/compiler-cli": "^4.4.6",
"#angular/core": "^4.4.6",
"#angular/forms": "^4.4.6",
"#angular/http": "^4.4.6",
"#angular/platform-browser": "^4.4.6",
"#angular/platform-browser-dynamic": "^4.4.6",
"#angular/platform-server": "^4.4.6",
"#angular/router": "^4.4.6",
Per the Material guide, run the following command in the project directory:
npm install --save #angular/material #angular/cdk
Update webpack.config.vendor.js to add the following lines to the treeShakableModules array, just after '#angular/router':
'#angular/material',
'#angular/material/prebuilt-themes/deeppurple-amber.css',
In app.module.browser.ts, import the module:
import { MatButtonModule } from '#angular/material';
#NgModule({
bootstrap: [ AppComponent ],
imports: [
BrowserModule,
MatButtonModule,
AppModuleShared
],
providers: [
{ provide: 'BASE_URL', useFactory: getBaseUrl }
]
})
In home.component.html, add the following line at the end of the file:
<button mat-raised-button>This is a button</button>
From the project directory, run webpack to update the vendor files:
webpack --config webpack.config.vendor.js
Build and run the application
Observe the home page button is not styled. There are no errors in the console suggesting missing styles or invalid attributes.
I have the following configuration:
Angular 4.4.6
Material 2.0.0-beta.12
Windows 10 Professional
TypeScript 2.4.1 (NPM)
Chrome Version 61.0.3163.100 (Official Build) (64-bit)
Verified the styles do exist, as specifying class="mat-raised-button" on the button has an effect (though it does not look like the raised button) it does change the interior styling of the button.
I note that the attribute does not appear to have any effect on the styling or content of the output HTML (versus what I see when inspecting the elements on the guide website), suggesting that something has gone wrong with the setup of the module, but I can't for the life of me figure out what that might be.
EDIT: By request, here is the webpack.config.vendor.js up to the boilerplate:
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const merge = require('webpack-merge');
const treeShakableModules = [
'#angular/animations',
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/forms',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'#angular/router',
'zone.js',
];
const nonTreeShakableModules = [
'#angular/cdk',
'#angular/material',
'#angular/material/button',
'#angular/material/prebuilt-themes/deeppurple-amber.css',
'bootstrap',
'bootstrap/dist/css/bootstrap.css',
'es6-promise',
'es6-shim',
'event-source-polyfill',
'jquery',
];
const allModules = treeShakableModules.concat(nonTreeShakableModules);
module.exports = (env) => {
const extractCSS = new ExtractTextPlugin('vendor.css');
const isDevBuild = !(env && env.prod);
const sharedConfig = {
stats: { modules: false },
resolve: { extensions: [ '.js' ] },
module: {
rules: [
{ test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, use: 'url-loader?limit=100000' }
]
},
output: {
publicPath: 'dist/',
filename: '[name].js',
library: '[name]_[hash]'
},
plugins: [
new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
new webpack.ContextReplacementPlugin(/\#angular\b.*\b(bundles|linker)/, path.join(__dirname, './ClientApp')), // Workaround for https://github.com/angular/angular/issues/11580
new webpack.ContextReplacementPlugin(/angular(\\|\/)core(\\|\/)#angular/, path.join(__dirname, './ClientApp')), // Workaround for https://github.com/angular/angular/issues/14898
new webpack.IgnorePlugin(/^vertx$/) // Workaround for https://github.com/stefanpenner/es6-promise/issues/100
]
};
... boilerplate follows this ...
So somewhat counterintuitively, the solution requires that the module importing be done in app.module.shared.ts, not app.module.browser.ts. If you are using the default Angular template, use the same steps as above, except for step 5, do the following:
Edit app.module.shared.ts to add the MatButtonModule module as an import, as follows:
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { RouterModule } from '#angular/router';
import { MatButtonModule } from '#angular/material/button';
import { AppComponent } from './components/app/app.component';
import { NavMenuComponent } from './components/navmenu/navmenu.component';
import { HomeComponent } from './components/home/home.component';
import { FetchDataComponent } from './components/fetchdata/fetchdata.component';
import { CounterComponent } from './components/counter/counter.component';
#NgModule({
declarations: [
AppComponent,
NavMenuComponent,
CounterComponent,
FetchDataComponent,
HomeComponent
],
imports: [
CommonModule,
HttpModule,
FormsModule,
MatButtonModule,
RouterModule.forRoot([
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'counter', component: CounterComponent },
{ path: 'fetch-data', component: FetchDataComponent },
{ path: '**', redirectTo: 'home' }
])
]
})
export class AppModuleShared {
}
Note also it is not necessary to add #angular/cdk or #angular/material/button to the modules list in webpack.config.vendor.js. It is sufficient to add the ones described in the guide.
See: https://github.com/angular/material2/issues/7997
According to official docs Here
You've to Import theming to your Global style file this is as simple as including one line in your styles.css file:
#import '~#angular/material/prebuilt-themes/deeppurple-amber.css';
or Alternatively, you can just reference the file directly.
Available pre-built themes:
deeppurple-amber.css
indigo-pink.css
pink-bluegrey.css
purple-green.css

Resources