I am having trouble with updating the css, img, fonts, and js admin files when I upgrade Django. I first noticed this when I upgraded to Django 2.0 (see here), and now the problem is worsening as I upgrade to 4.0.
The backend functionality is working perfectly well. But now when I access the admin console, the homepage remains on the top of the browser page, even when I navigate to different models.
I noticed that none of the /static/admin/ files (css, js, img, fonts) were updated on my local machine when upgrading from Django 2.2.24 to 4.0. Should I have expected these files to update along with Django? Am I missing a step to ensure that the admin static files are updated to reflect the newest version of Django?
Attempted Fixes
I have run collectstatic, but it looks like that is simply copying my local static/admin files to AWS S3, where I normally store static files. Should I not have static/admin files on my local machine?
I copied the static/admin files from Django.contrib cp -a /Users/username/.virtualenvs/rs/lib/python3.9/site-packages/django/contrib/admin/. /Users/username/Documents/myproject/static/. This actually worked, but seems a bit hacky. I must not be doing something right for these files to not update upon Django upgrade.
I should note that I am using gulp.js. Could this be a problem when I run collectstatic? Here is my gulpfile:
const gulp = require('gulp');
const util = require('gulp-util');
const plumber = require('gulp-plumber');
const tap = require('gulp-tap');
const del = require('del');
const sass = require('gulp-sass');
const cssnano = require('gulp-cssnano');
const autoprefixr = require('gulp-autoprefixer');
const buffer = require('vinyl-buffer');
const uglify = require('gulp-uglify');
const babelify = require('babelify');
const browserify = require('browserify');
const concat = require('gulp-concat');
const runSequence = require('run-sequence');
const gulpif = require('gulp-if');
gulp.task('clean', function () {
return del([
'static/img/**/*',
'static/css/**/*',
'static/js/**/*'
]);
});
gulp.task('sass', function () {
const config = {
src: ['./assets/styles/myproject.scss', './assets/styles/myproject-dashboard.scss'],
dest: './static/css',
sass: {
includePaths: [
'node_modules/bootstrap-sass/assets/stylesheets'
]
},
autoprefixr: {
browsers: ['last 4 versions'],
cascade: false
}
};
return gulp.src(config.src)
.pipe(plumber())
.pipe(sass(config.sass))
.pipe(autoprefixr(config.autoprefixr))
.pipe(gulpif(util.env.production, cssnano()))
.pipe(plumber.stop())
.pipe(gulp.dest(config.dest));
});
gulp.task('images', function () {
return gulp.src('./assets/images/**/*')
.pipe(gulp.dest('./static/img'));
});
gulp.task('vendor-scripts', function () {
const config = {
src: [
'./node_modules/jquery/dist/jquery.min.js',
'./node_modules/bootstrap-sass/assets/javascripts/bootstrap.min.js',
'./node_modules/responsive-toolkit/dist/bootstrap-toolkit.min.js',
'./node_modules/jquery-circle-progress/dist/circle-progress.min.js',
],
dest: './static/js/vendor'
};
return gulp.src(config.src)
// .pipe(concat('vendor.js'))
.pipe(gulp.dest(config.dest));
});
gulp.task('scripts', function () {
const config = {
src: './assets/scripts/**/*.js',
dest: './static/js/'
};
return gulp.src(config.src, { read: false }) // no need of reading file because browserify does.
.pipe(plumber())
// transform file objects using gulp-tap plugin
.pipe(tap(function (file) {
// replace file contents with browserify's bundle stream
file.contents = browserify({
entries: file.path,
transform: [babelify],
paths: [
'./node_modules/'
]
}).bundle();
}))
// transform streaming contents into buffer contents
.pipe(buffer())
.pipe(gulpif(util.env.production, uglify()))
.pipe(plumber.stop())
.pipe(gulp.dest(config.dest));
});
gulp.task('build', ['sass', 'vendor-scripts', 'scripts', 'images']);
gulp.task('default', ['watch']);
gulp.task('watch', ['sass', 'vendor-scripts', 'scripts', 'images'], function () {
gulp.watch('./assets/styles/**/*.scss', ['sass']);
gulp.watch('./assets/images/**/*', ['images']);
gulp.watch('./assets/scripts/**/*.js', ['scripts']);
});
Related
when I update webpack 4 to 5, the error exits.
I have a webpackDevServer.js which include the error message 'error'
// webpackDevServer.js
module.exports = function(proxy, allowedHost) {
return {
before(app, server) {
if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(app);
}
// This lets us fetch source contents from webpack for the error overlay
app.use(evalSourceMapMiddleware(server));
// This lets us open files from the runtime error overlay.
app.use(errorOverlayMiddleware());
// This service worker file is effectively a 'no-op' that will reset any
// previous service worker registered for the same host:port combination.
// We do this in development to avoid hitting the production cache if
// it used the same host and port.
// https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
app.use(noopServiceWorkerMiddleware());
},
};
};
I use the above file in a start.js file, when I run the project, I type node scripts/start.js
// start.js
...
const createDevServerConfig = require('../config/webpackDevServer.config');
...
const serverConfig = createDevServerConfig(
proxyConfig,
urls.lanUrlForConfig
);
const devServer = new WebpackDevServer(compiler, serverConfig);
then it throws an error
configuration has an unknown property 'before'. These properties are valid:
object { bonjour?, client?, compress?, dev?, firewall?, headers?, historyApiFallback?, host?, hot?, http2?, https?, injectClient?, injectHot?, liveReload?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, openPage?, overlay?, port?, proxy?, public?, setupExitSignals?, static?, stdin?, transportMode?, useLocalIp? }
here is my package.json
"webpack": "^5.20.2",
"webpack-dev-server": "^4.0.0-beta.0",
"webpack-manifest-plugin": "2.0.4",
"workbox-webpack-plugin": "^6.1.0"
You have to change before to the onBeforeSetupMiddleware. Link with migration description from v3 to v4. https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md
In case, something will change on the migration guide, details are attached below
v3:
module.exports = {
devServer: {
after: function (app, server, compiler) {
app.get("/some/path", function (req, res) {
res.json({ custom: "response" });
});
},
},
};
v4:
module.exports = {
devServer: {
onAfterSetupMiddleware: function (devServer) {
devServer.app.get("/some/path", function (req, res) {
res.json({ custom: "response" });
});
},
},
};
fxxk, I'm stupid, when i search some key word (eg: onBeforeSetupMiddleware), I found the github of webpack-dev-server which tell the changes in new version 4.0.0 beta. https://github.com/webpack/webpack-dev-server/releases
I want to generate CSS like this:
In normal chunks used by my web application.
main.css 1.chunk.css 2.chunk.css .... etc
And a single file
server.css
Because I use server.css in backend
I tried to use this https://webpack.js.org/plugins/mini-css-extract-plugin/#extracting-all-css-in-a-single-file but always get one css emitted.
Finally I use a script in node to merge the css and not change the default configuration in webpack. And also use npm-run-all to integrate the script in build process in package.json
const fs = require('fs');
fs.readdir('build/static/css', function (err,files){
if(err){
console.log(err)
}
files
.filter((file) => {
return file.match(/.*\.css$/)
})
.sort((a, b) => {
if (a.startsWith("main") || b.startsWith("main")) {
return -1;
} else {
return a.localeCompare(b);
}
})
.map(file => {
const data = fs.readFileSync(`build/static/css/${file}`, 'utf8');
fs.appendFileSync('build/static/css/server.css', data+'\n')
});
})
Currently Jest is failing the tests because it cannot find the module called inside a component:
FAIL tests/Unit/VHeaderBar.spec.ts
● Test suite failed to run
Cannot find module '##/public/assets/images/placeholder.png' from 'VHeaderBar.vue'
at Resolver.resolveModule (node_modules/jest-runtime/node_modules/jest-resolve/build/index.js:221:17)
at src/components/VHeaderBar.vue:687:18
at Object.<anonymous> (src/components/VHeaderBar.vue:749:3)
Case
In NuxtJs the ## signs refer to the root directory, because in the end solution we want to store images in the public folder or storage folder, which is located in the root of the project.
When running tests jest checks the src folder, then tries to mount the images stored from the root and can't find them.
I have tried many different ways to fix this issue, but can't seem to find the solution.
Here's a shortlist of what I already tried:
Changing regex to check for image files and lead it to the correct folder using the moduleNameMapper option in the Jest config file.
I read something on Stack about using a "mock" folder that exports the images files through javascript, but that didn't work.
Using the modulePaths option in the Jest config file.
Creating an alias in the tsconfig.js for the assets folder and using that in the moduleNameMapper
Tried a different approach in the VueJS component and test file to load assets, which broke the compiling process (so I reverted that).
Current Jest Config file
module.exports = {
moduleFileExtensions: [
"ts",
"tsx",
"vue",
"js",
"json"
],
watchman: false,
moduleNameMapper: {
"/\.(gif|jpg|jpeg|tiff|png)$/i": "<rootDir>/public/assets/images/$1",
"^#/(.*)$": "<rootDir>/src/$1",
"^~/(.*)$": "<rootDir>/src/$1",
"^~~/(.*)$": "<rootDir>/src/$1"
},
transform: {
// process js with `babel-jest`
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
// process `*.vue` files with `vue-jest`
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest",
// process `*.ts` files with `ts-jest`
"^.+\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest",
},
snapshotSerializers: [
"<rootDir>/node_modules/jest-serializer-vue"
],
collectCoverage: true,
collectCoverageFrom: [
"<rootDir>/src/components/**/*.vue",
"<rootDir>/src/pages/**/*.vue",
"<rootDir>/src/layouts/**/*.vue"
],
testMatch: [
'**/tests/Unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
],
}
Current folder structure (only folders we use for the test)
project folder
- public
-- assets
--- **images**
- src
-- components
--- **mounted component** (works)
- tests
-- Unit
--- mountedComponent.spec.ts
Any suggestions?
Do I fix the jest.config?
Is there something wrong with the syntax?
Do I have to fix the tsconfig?
I've had a similar issue and it goes down to typescript not being able to import that file.
I've solved it by adding file type definition to files.d.ts:
declare module "*.pdf" {
const file: Buffer;
export default file;
}
declare module "*.jpeg" {
const src: string;
export default src;
}
declare module "*.png" {
const src: string;
export default src;
}
Referring to this file in tsconfig.json:
{
"compilerOptions": {
/* ... */
},
"files": ["./src/#types/files.d.ts"],
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
And adding file transforms to jest.config.js:
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
roots: ["<rootDir>/src/"],
moduleNameMapper: {
"#app/(.*)": "<rootDir>/src/$1",
"#lib/(.*)": "<rootDir>/src/lib/$1",
},
transform: { // Transforms here
"\\.(gql|graphql)$": "#jagi/jest-transform-graphql",
"\\.(html|html|txt|pem|key)$": "./jest-transform-text.js",
"\\.(p12|pdf|otf|ttf)$": "./jest-transform-buffer.js",
"^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
coverageReporters: ["text", "lcov"],
};
Examples of transform files:
// jest-transform-buffer.js
"use strict";
const fs = require("fs");
module.exports = {
process(src, filename) {
const data = fs.readFileSync(filename, "hex");
return (
'module.exports=Buffer.from("' +
data +
'","hex");module.exports.default=module.exports;'
);
},
};
And for images (or other files where you only need a filename) from create react app:
'use strict';
const path = require('path');
const camelcase = require('camelcase');
// This is a custom Jest transformer turning file imports into filenames.
// http://facebook.github.io/jest/docs/en/webpack.html
module.exports = {
process(src, filename) {
const assetFilename = JSON.stringify(path.basename(filename));
if (filename.match(/\.svg$/)) {
// Based on how SVGR generates a component name:
// https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6
const pascalCaseFilename = camelcase(path.parse(filename).name, {
pascalCase: true,
});
const componentName = `Svg${pascalCaseFilename}`;
return `const React = require('react');
module.exports = {
__esModule: true,
default: ${assetFilename},
ReactComponent: React.forwardRef(function ${componentName}(props, ref) {
return {
$$typeof: Symbol.for('react.element'),
type: 'svg',
ref: ref,
key: null,
props: Object.assign({}, props, {
children: ${assetFilename}
})
};
}),
};`;
}
return `module.exports = ${assetFilename};`;
},
};
I am using vue/cli 3 configured for cypress e2e tests. The e2e test scenario works fine but I also wish to use cypress for unit tests. I installed cypress-vue-unit-test but when loading a single component (using mountVue) cypress fails to interpret the Vue syntax ( etc).
I presume I have to add configuration so that the correct web pack loaders are used at the preprocessor stage when cypress bundles the files. I have been unable to figure out how to accomplish this as there is no web pack config file in my project and I am not sure how to modify the preconfigured set-up. Can anyone guide me?
Thanks phoet, you pointed me in the right direction. The solution was to place the configuration in tests/e2e/plugins/index.js with the following content (probably could be refined):
const webpack = require("#cypress/webpack-preprocessor");
const VueLoader = require("vue-loader/lib/plugin");
const webpack_vue_cypress_config = {
webpackOptions: {
module: {
rules: [
{
test: /\.vue$/,
loader: "vue-loader"
},
{
test: /\.css$/,
use: ["vue-style-loader", "css-loader"]
}
]
},
resolve: {
extensions: [".js", ".vue", ".json"],
alias: {
vue$: "vue/dist/vue.esm.js",
"#": "../../"
}
},
plugins: [new VueLoader()]
},
watchOptions: {}
};
module.exports = (on, config) => {
on("file:preprocessor", webpack(webpack_vue_cypress_config));
return Object.assign({}, config, {
fixturesFolder: "tests/e2e/fixtures",
integrationFolder: "tests/e2e/specs",
screenshotsFolder: "tests/e2e/screenshots",
videosFolder: "tests/e2e/videos",
supportFile: "tests/e2e/support/index.js"
});
};
Thanks Linus; that's much cleaner
const webpack = require("#cypress/webpack-preprocessor");
const options = {
webpackOptions: require("#vue/cli-service/webpack.config.js"),
watchOptions: {}
};
module.exports = (on, config) => {
on("file:preprocessor", webpack(options));
return Object.assign({}, config, {
fixturesFolder: "tests/e2e/fixtures",
integrationFolder: "tests/e2e/specs",
screenshotsFolder: "tests/e2e/screenshots",
videosFolder: "tests/e2e/videos",
supportFile: "tests/e2e/support/index.js"
});
};
I am using ionic 2.
I need generate the icon for one signal notification.
I tried to this
Add a file to your hooks directory inside the after_prepare folder called 030_copy_android_notification_icons.js
Put the following code in it:
var filestocopy = [{
"resources/android/icon/drawable-hdpi-icon.png":
"platforms/android/res/drawable-hdpi/ic_stat_onesignal_default.png"
}, {
"resources/android/icon/drawable-mdpi-icon.png":
"platforms/android/res/drawable-mdpi/ic_stat_onesignal_default.png"
}, {
"resources/android/icon/drawable-xhdpi-icon.png":
"platforms/android/res/drawable-xhdpi/ic_stat_onesignal_default.png"
}, {
"resources/android/icon/drawable-xxhdpi-icon.png":
"platforms/android/res/drawable-xxhdpi/ic_stat_onesignal_default.png"
}, {
"resources/android/icon/drawable-xxxhdpi-icon.png":
"platforms/android/res/drawable-xxxhdpi/ic_stat_onesignal_default.png"
} ];
var fs = require('fs');
var path = require('path');
// no need to configure below
var rootdir = process.argv[2];
filestocopy.forEach(function(obj) {
Object.keys(obj).forEach(function(key) {
var val = obj[key];
var srcfile = path.join(rootdir, key);
var destfile = path.join(rootdir, val);
//console.log("copying "+srcfile+" to "+destfile);
var destdir = path.dirname(destfile);
if (fs.existsSync(srcfile) && fs.existsSync(destdir)) {
fs.createReadStream(srcfile).pipe(
fs.createWriteStream(destfile));
}
});
});
I have no idea.
Kindly advice me,
Thanks
I have faced with same issue. Your way is correct, putting 030_copy_android_notification_icons.js file under {root}/hooks/after_prepare. Also note that, filename is not important.
Then to run script you need to run below comment:
ionic cordova prepare android
With this, your script will be run. But maybe your problem may be similar to mine. If you use windows, while coping files from resources/android/icon/ to platforms/android/res/, because of missing of target folders, script is not able to copy operation. That's why a simple code should be added to code.
var destdir = path.dirname(destfile);
if (!fs.existsSync(destdir)){
fs.mkdirSync(destdir);
}